【问题标题】:Qt qUncompress giving "could not allocate enough memory to uncompress data"Qt qUncompress 给出“无法分配足够的内存来解压缩数据”
【发布时间】:2014-08-17 19:34:49
【问题描述】:

我有以下代码在调用错误时失败:

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),但是有没有办法避免这样做?

【问题讨论】:

  • 你把这个函数称为 decStage3(qCompress(arr)) 吗? (您在调用函数之前是否压缩数据?)如果您不压缩数据,请尝试执行此操作。也许在这之后你会得到 qUncompress: Z_DATA_ERROR: Input data is corrupted 错误???
  • 数据很好,因为它来自另一个压缩程序。如果我遗漏一个字节,我会得到无效数据错误,所以我相信数据是正确的。
  • @TenG 我也遇到过类似的问题,解决方法是直接在 DEFLATEd 流上使用 tinfl 或 zlib。也可能是标题的问题,它是前置的。
  • @user1095106 - 谢谢,这应该给我一个出路。是否有直接在 zlib 中执行上述操作的示例?我得到了 和“JlCompress.h”的#includes。
  • 这个问题似乎是题外话,因为它是关于 qUncompress 的一个明确记录的方面。

标签: qt memory-management zlib


【解决方案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,因为这对于我们期望的数据来说已经足够了。

【讨论】:

  • 记录在案:“注意:如果要使用此函数解压缩使用 zlib 压缩的外部数据,首先需要在包含数据的字节数组中添加一个四字节的标头。标头必须包含未压缩数据的预期长度(以字节为单位),以无符号、大端、32 位整数表示。"
猜你喜欢
  • 1970-01-01
  • 2023-04-05
  • 2022-01-26
  • 2016-06-19
  • 2017-04-04
  • 2021-03-31
  • 2021-06-12
  • 2020-05-05
  • 1970-01-01
相关资源
最近更新 更多