Qt qUncompress give"无法分配足够的内存来解压缩数据"

时间:2014-08-17 19:34:49

标签: qt memory-management zlib

我有以下代码,当使用错误调用时失败:

qUncompress: could not allocate enough memory to uncompress data

代码:

QString decStage3 ( QByteArray s )
{
    printf ( "3a: length in %d\n", s.length());
    QByteArray bData = QByteArray::fromHex(s );
    printf ( "3b: length ba %d\n", bData.length());
    printf ( "3c: ba [%s]\n", qPrintable(bData.toHex()));
    printf ( "3d: mem [%d]\n", bData.capacity() );

    QByteArray dS = qUncompress( bData );
   // QByteArray::fromHex(s.toLatin1());
    return (dS.data());
}

示例输入为“789C0B492D2E5170492C490400101E033B”(==“测试数据”)。

更新:根据切尔诺贝利的建议,我决定添加如下直接测试:

void tst ( QByteArray b0 )
{
    QByteArray b1 = qCompress (b0);
    printf ( "[%s] %d = [%s] %d\n", qPrintable(b0), b0.length(), qPrintable(b1.toHex()), b1.length());
    QByteArray b2 = qUncompress (b1);
    printf ( "uncomp = [%s]\n", qPrintable(b2));
}

然后测试:

tst ("Hello");
tst ("Hello World");
tst ("Hello World Nice To See You");

这给出了以下内容:

[Hello] 5 = [00000005789cf348cdc9c90700058c01f5] 17
uncomp = [Hello]
[Hello World] 11 = [0000000b789cf348cdc9c95708cf2fca490100180b041d] 23
uncomp = [Hello World]
[Hello World Nice To See You] 27 = [0000001b789cf348cdc9c95708cf2fca4951f0cb4c4e5508c957084e4d5588cc2f050082f70939] 39
uncomp = [Hello World Nice To See You]

请注意,前8个字节现在看起来保持原始字符串的长度(十六进制)。我之前没有遇到过这种行为。我可以修改源程序以包含它(来自另一个系统,使用Java),但有没有办法避免必须这样做?

1 个答案:

答案 0 :(得分:1)

通过在zip数据之前预先设置虚拟长度(从789c开始)来修复(或者更确切地说是工作):

QString decStage3 ( QByteArray s )
{
    printf ( "3a: length in %d\n", s.length());
    QByteArray bData = QByteArray::fromHex("00004000") + QByteArray::fromHex(s );
    printf ( "3b: length ba %d\n", bData.length());
    printf ( "3c: ba [%s]\n", qPrintable(bData.toHex()));
    printf ( "3d: mem [%d]\n", bData.capacity() );

    QByteArray dS = qUncompress( bData );
   // QByteArray::fromHex(s.toLatin1());
    return (dS.data());
}

这是我声明bData的行,在" 00004000"之前加上它。评估为16K。事实证明,虽然在压缩时它表示未压缩数据的长度,但在非压缩时它实际上并不需要是准确的长度。所以,假设这更多地与内部使用的内存抓取进行解压缩,我选择了16K,因为这对于我们期望的数据来说已经足够了。