为什么zlib deflate()挂?

Ale*_*lds 1 c gdb zlib stream deflate

我的问题是我的程序依赖于使用zlib的deflate()功能.

我首先初始化我z_stream,如下:

int setupGzipOutputStream(z_stream zStream) {
    int zError;
    zStream.zalloc = Z_NULL;
    zStream.zfree = Z_NULL;
    zStream.opaque = Z_NULL;

    zError = deflateInit(&zStream, Z_COMPRESSION_LEVEL);

    /* error handling code to test if zError != Z_OK... */
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用以下函数将数据写入我的z-stream:

int compressDataToGzipOutputStream(unsigned char *myData, z_stream zStream, Boolean flushZStreamFlag) {
    int zError;
    int zOutHave;
    FILE *outFp = stdout;
    unsigned char zBuffer[Z_BUFFER_MAX_LENGTH] = {0};

    zStream.next_in = myData;
    zStream.avail_in = strlen(myData); /* myData is a null-terminated string */
    do {
        zStream.avail_out = Z_BUFFER_MAX_LENGTH;
        zStream.next_out = zBuffer;

        zError = deflate(&zStream, (flushZStreamFlag == kFalse) ? Z_NO_FLUSH : Z_FINISH);

        /* error handling code to test if zError != Z_OK... */
        zOutHave = Z_BUFFER_MAX_LENGTH - zStream.avail_out;
        fwrite(zBuffer, sizeof(unsigned char), zOutHave, outFp);
        fflush(outFp);
    } while (zStream.avail_out == 0);

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

我将这两个函数(简化为了提出这个问题的目的)称为如下:

z_stream zOutStream;

setupGzipOutputStream(zOutStream);

compressDataToGzipOutputStream(data, zOutStream, kFalse); 
compressDataToGzipOutputStream(data, zOutStream, kFalse);
...
compressDataToGzipOutputStream(data, zOutStream, kTrue);
Run Code Online (Sandbox Code Playgroud)

然后我用它来分解zOutStream结构deflateEnd().

kTrue最后一个压缩步骤的值将Z_FINISH标志发送给deflate(),而不是Z_NO_FLUSH.

它挂在以下行:

zError = deflate(&zStream, (flushZStreamFlag == kFalse) ? Z_NO_FLUSH : Z_FINISH);
Run Code Online (Sandbox Code Playgroud)

然后我尝试使用gdb.我break在这一行设置了一个程序挂起的行.

在这个断点,我可以看到变量的值zStream,flushZStreamFlag等等.该zStream变量不是NULL,我可以确认print zStream,print zStream.next_in等,这些填充了我感兴趣的数据.

如果I型nextgdb,那么这行代码被处理,并且在整个过程挂起,这是我与前和这行代码后日志语句验证.显示"之前"日志语句,但"之后"语句不显示.

我的问题是:为什么要deflate()挂在这里?我没有正确初始化输出流吗?没用deflate()正确吗?我一直在试图解决这个问题,但是没有运气.感谢您的任何建议.

Jas*_*onD 5

你的函数应该使用指向z_stream的指针,而不是传入结构.你的init函数初始化什么是有效的本地副本,它将被丢弃.然后你的压缩函数会传递一个垃圾z_stream.

例如:

int setupGzipOutputStream(z_stream *zStream) {
    int zError;
    zStream->zalloc = Z_NULL;
    ...
}

... etc.
Run Code Online (Sandbox Code Playgroud)

看起来您的压缩函数没有考虑字符串末尾的null,因此当您尝试重新膨胀数据时可能会导致问题.

zStream.avail_in = strlen(myData);
Run Code Online (Sandbox Code Playgroud)

可能想成为:

zStream.avail_in = strlen(myData) + 1;
Run Code Online (Sandbox Code Playgroud)