0

チュートリアルから取得したこのコード スニペットを使用しています。入力ファイルからのデータを圧縮し、出力ファイルに入れることを意図しています。ただし、実行時にセグメンテーション違反が発生します。

int map_Compress(char *inmapfile, char *outmapfile)
{
    FILE *infile = fopen(inmapfile, "rb");
    gzFile outfile = gzopen(outmapfile, "wb");
    if (!infile || !outfile) return -1;
    char inbuffer[1];
    int num_read = 0;
    unsigned long total_read = 0;
    while ((num_read = fread(&inbuffer, 1, sizeof(inbuffer), infile)) > 0)
    {
        printf("%d\n",total_read);
        total_read += num_read;
        gzwrite(outfile, inbuffer, num_read);
    }
    fclose(infile);
    gzclose(outfile);
    return total_read;
}

そして、それは次のように呼び出されています:

int main()
{
    if (map_Compress("maps/main.map", "maps/main.mz") < 0)
    {
        printf("Compression failed, couldn't open file(s)\n");
    }
    return 0;
}

このセグメンテーション違反は何ですか?これが呼び出されたときに画面に表示されるのは次のとおりです。

0
1

そして、プログラムがクラッシュします... 何が問題なのですか? 入力ファイルにガベージ コンテンツが含まれているため、関数はデータを圧縮して出力ファイルに入れるべきではありませんか?

助けてください、私はそれが私が見落とした単純な問題だと確信しています:)

4

2 に答える 2

2

示されているコードには、クラッシュの原因となる問題はありません。それはどこかで起こっているに違いない。クラッシュした場所を表示するデバッガーはありませんか?

いくつかのマイナーな修正が必要です。移植性のために、 を使用する代わりに、と比較infileする必要がありNULLます。が失敗してが成功した場合は、巨大なメモリ リークを避けるためにエラーを返す必要があります。およびその逆。フォーマットは. (コンパイラの警告レベルを少し上げる必要があります。)最後に出力された数値は実際に読み取られた数値とは異なるため、 はおそらく に追加した後であるはずです。を返すので、ではなくを返す必要があります。あなたには異質なものがありますoutfileZ_NULL!fopen()gzopen()gzclose()printf%luprintftotal_readmap_compress()unsigned longinttotal_read&fread()—害はありませんが、混乱する可能性がありinbuffer、割り当てられたバッファーに変更すると失敗する可能性があります。

コードは、1 バイトよりも大きな入力バッファーをサポートするように適切に設定されています。効率のためには、はるかに大きくする必要があります。少なくとも 4K または 8K。

于 2012-11-03T18:53:52.890 に答える
-3

それ以外の

fread(&inbuffer, 1

試す

fread(inbuffer, 1

ここ:

gzwrite(outfile, inbuffer, num_read);

この関数が何をするのかはわかりませんが、おそらく、1 バイトしか含まれていない inbuffer から num_read バイトを読み取ろうとしています。

于 2012-11-03T08:27:34.817 に答える