【问题标题】:Z_MEM_ERROR Zlib deflateInit2() embedded deviceZ_MEM_ERROR Zlib deflateInit2() 嵌入式设备
【发布时间】:2018-12-19 13:55:56
【问题描述】:

请注意这段代码:

  #define CHUNK 0x4000
  z_stream strm;
  unsigned char out[CHUNK];
  int ret;

  strm.zalloc = Z_NULL;
  strm.zfree = Z_NULL;
  strm.opaque = Z_NULL;

  int windowsBits = 15;
  int GZIP_ENCODING = 16;

  ret = deflateInit2(&strm, Z_BEST_SPEED, Z_DEFLATED, windowsBits | GZIP_ENCODING, 1, 
                     Z_DEFAULT_STRATEGY);
  if(ret == Z_OK) {
     strm.next_in = (z_const unsigned char *)answer;
     strm.avail_in = strlen(answer);
     do {
        strm.avail_out = CHUNK;
        strm.next_out = out;
        ret = deflate(&strm, Z_FINISH);
     } while (strm.avail_out == 0);
  }

    /* clean up and return */
  (void)deflateEnd(&strm);

使用answer(200 个元素的无符号字符数组,最后一个为 \0)填充在 4 个声明和其余部分之间。

它在deflateInit2 Z_MEM_ERROR 上崩溃。

我正在开发 STM32F4(微控制器)。在尝试实施压缩之前,我的 RAM 几乎已满 (~87%)。

当我使用不同的参数时,我让这部分工作了一次,但后来在程序中出现错误(因为我想将 gzip'ed 字符串发送到 HTTP 输出,错误是:

无法识别的编码。

我有:~30 KB 的可用 RAM。

【问题讨论】:

    标签: c compression gzip zlib stm32


    【解决方案1】:

    zlib 的 deflate 通常需要大约 256K 的 RAM。见zlib technical details。 30K 有点限制,但您仍然可以使用memLevelwindowBits 参数来减少内存占用以减少内存占用。从该页面:

    deflate memory usage (bytes) = (1 << (windowBits+2)) + (1 << (memLevel+9))
    

    因此,您可以使用 5 的 memLevel 和 11 的 windowBits 到达那里,大约需要 24K(加上一些其他结构)。这会在一定程度上降低压缩效率,但至少它会起作用。 (您仍然可以将 16 添加到 windowBits 以进行 gzip 编码。)

    【讨论】:

    • 好的,谢谢,它可以工作,但我遇到了另一个问题:我的输出缓冲区现在在放气后的“正常”字符之间有一些空字符。我曾经调用 strlen(out buffer) 。这是正常行为吗?以下问题:我模拟流式传输意味着我的字符串answer 被多次填充。我需要做什么 ?多次使用 deflateinit2 + deflate ?因为它现在似乎只能工作一次..
    • deflate 的结果是二进制数据,与任何其他字节值相同的概率为零。您不能将其视为“字符串”。
    • 您可以查看this example了解如何使用deflateinflate函数。
    • 好的,谢谢。是的,我已经完成了,但这并不是我的实际情况,因为在示例中,我们得到了一个完整的缓冲区。同时,我想一个一个地压缩缓冲区(并在每次操作后立即发送)
    • 您需要提出一个新问题,提供有关您正在尝试做什么的更多信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多