2011-11-18 57 views
0

我有一些压缩的二进制数据和一个API调用来解压缩它需要一个预先分配的目标缓冲区。没有任何通过API的方式告诉我解压缩数据的大小。所以我可以malloc超大缓冲区解压缩到,但我想然后调整大小(或复制到)一个正确大小的内存缓冲区。那么,我如何(确实可以)在超大缓冲区中确定解压缩的二进制数据的实际大小?如何确定一个malloc'ed缓冲区的实际用法

(我不控制数据的压缩,所以我不可能提前知道做什么期望的大小,我不能写头的文件。)

+0

如果您提供的缓冲区太小,解压缩API会失败吗?如果是这样,也许它会告诉你应该提供多大的缓冲区?如果您希望我们帮助您,请提供更多信息。 – 2011-11-18 12:58:40

+0

我真的会切换库,因为你正在使用的显然是不好的。 –

+0

解压缩后甚至无法获得未压缩数据的大小,例如像来自uncomress函数的返回值?你在使用什么API? –

回答

0

通常这个信息在压缩时提供的(以例如看看7-Zip LZMA SDK)。

无法通过您现在提供的信息知道解压缩数据的实际大小(或实际使用的部件的大小)。

0

如果解压缩步骤没有给你解压缩的大小作为返回值或某种方式的“out”参数,你不能。

无法确定有多少数据写入缓冲区(调试器/ valgrind类型检查之外)。

2

正如其他人所说,如果你的API没有提供它,没有好的方法来做到这一点。

我几乎不想暗示该怕的是你要这个建议,有一些关键的部分应用程序的依赖于它,但是......

一个heurstic将填补你的缓冲区有一些“毒药”模式,然后解压缩成它。然后,在解压缩后,扫描缓冲区以查找第一个出现的毒药模式。

这是一种启发式方法,因为完全可以想象,解压缩的数据可能碰巧发生了你的毒药模式。除非你有确切的关于数据的领域知识,并且可以选择一种你知道不可能存在的模式。

即使如此,充其量也是一个不完美的解决方案。

+2

而不是扫描第一次出现的缓冲区,从结尾向后扫描,直到您不再看到毒性模式。至少你只有在你的解压缩数据碰到毒药模式时才会遇到问题,而不是在缓冲区内的任何地方发生。 – Vicky

+1

为了使这更健壮,甚至可以使用两种不同的毒药模式进行两次解压缩,并验证结束是否发生在相同的地方。这太可怕了,取决于你的限制,它不会给你提供比保留原有的太大缓冲区更好的性能,但至少它可能是一个脱离角落的方式。 – Vicky

+1

你肯定知道如果你解压两次,第一次用00填充缓冲区,第二次用FF填充缓冲区。但我当然不提倡这样的黑客攻击。 – indiv

0

解决此问题的一种复杂方法是​​将解压缩两次到超大缓冲区中。

在这两种情况下,您都需要一个“随机模式”。从结尾开始,您计算与该模式对应的字节数,并检测解压缩序列的结束位置。

还是呢?也许,偶然地,解压缩序列的最后一个字节对应于这个确切位置上的随机字节。所以最终解压后的大小可能会大于检测到的大小。如果你的模式是真正的随机的,它不应该超过几个字节。

您需要用随机模式再次填充缓冲区,但是不同的模式。确保在每个位置新的随机模式具有与旧的随机模式不同的值。为了获得更快的速度,您没有义务填充完整的缓冲区:您可能会将新模式限制为之前的几个字节,并在第一次检测到结束之后再多一些字节。 32个字节就足够了,因为很多字节不可能偶然地对应于第一个产生的随机模式。

解压缩第二次。再次检测模式不同的地方。取第一个和第二个结束检测之间的两个值中较大的一个。这是你解压缩的大小。

-1

你应该检查自由编译器/操作系统 的工作原理,并执行相同的操作。 免费不占用malloced数据的大小,但它以某种方式知道有多少空闲的权利;) 通常大小存储在分配的缓冲区之前,不知道究竟如何maby字节再次依赖于os/arch/compiler

+0

这将作出一个很好的评论,但作为一个答案... -1'd – vdbuilder