1

私の問題は、私のプログラムが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;
}

次の関数を使用して、zストリームにデータを書き込もうとしています。

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;
}

私はこれらの2つの関数を次のように呼び出します(この質問をするために簡略化して):

z_stream zOutStream;

setupGzipOutputStream(zOutStream);

compressDataToGzipOutputStream(data, zOutStream, kFalse); 
compressDataToGzipOutputStream(data, zOutStream, kFalse);
...
compressDataToGzipOutputStream(data, zOutStream, kTrue);

zOutStream次に、構造体を。で分解しdeflateEnd()ます。

kTrue最後の圧縮ステップの値は、Z_FINISHフラグを。deflate()ではなくに送信しますZ_NO_FLUSH

次の行にぶら下がっています。

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

次に、を使用してみgdbました。breakプログラムがぶら下がっているこの行にを設定します。

このブレークポイントでは、変数の値などを確認できzStreamますflushZStreamFlagzStream変数はではありません。これは、関心のあるデータが入力されている、などで確認NULLできます。print zStreamprint zStream.next_in

を入力nextするgdbと、このコード行が処理され、プロセス全体がハングします。これは、このコード行の前後のログステートメントで確認します。「before」ログステートメントは表示されますが、「after」ステートメントは表示されません。

私の質問は:なぜdeflate()ここにぶら下がっているのですか?出力ストリームを正しく初期化していないのですか?deflate()正しく使用していませんか?私はこれを解決しようとして壁に頭をぶつけてきましたが、運がありません。あなたが持っているかもしれないアドバイスをありがとう。

4

1 に答える 1

5

関数は、構造体を渡すのではなく、z_streamへのポインターを受け取る必要があります。init関数は、事実上ローカルコピーであるものを初期化しており、これは破棄されます。次に、圧縮関数にガベージz_streamが渡されます。

例えば:

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

... etc.

また、圧縮関数が文字列の末尾のnullを考慮していないように見えるため、データを再膨張させようとすると問題が発生する可能性があります。

zStream.avail_in = strlen(myData);

なりたいかもしれません:

zStream.avail_in = strlen(myData) + 1;
于 2012-12-14T13:44:08.047 に答える