0

編集:いくつかの質問に答えるために、これは改訂されたがまだ機能していないコードです(ほとんどはそもそもそこにありましたが、ファイルポインタなどを初期化したことを明示する必要がありました)。繰り返しますが、exp()の前に書き込みを追加するか、exp()を完全に削除した場合にのみ機能します。

FILE *outfile;
char *outfilename;
outfilename = (char *)malloc(FILENAME_MAX*sizeof(char));
strcpy(outfilename, "outfile.txt");
outfile = fopen(realoutfilename, "w");

/* If this is uncommented, there isn't a segfault
if(realoutfile!=NULL && imoutfile!=NULL){
    fprintf(outfile, "\r\n");
    fseek(outfile,0,SEEK_SET);
}
*/

gauss = (double*) calloc(points, sizeof(double));

/* Maths and stuff */

if(outfile!=NULL){
    for(i=0;i<points;i++){
        /* this prints fine */
        printf(outfile, "%g,\r\n", gauss[i]);
        /* Seg fault is here */
        fprintf(outfile, "%g,\r\n", gauss[i]);

    }
}
fclose(outfile);
free(outfile);

そして私はコンパイルしています:

gcc main.c -lm -Wall -Wextra -Werror -Wshadow -g -o main

明確にするために、それは関数の終わりに到達しません-したがって、それがクラッシュするのは解放ではありません。クラッシュは、そのforループでファイルに書き込もうとしたときに発生します。

私が言ったように、exp()がオーバーフローまたはアンダーフローしていないことを確認しました。出力をprintfできますが、ファイルの書き込みはノーノーです。exp(2)などの単純な呼び出しを試みても失敗します。

gdbのバックトレースは次のとおりです(私はgdbにあまり詳しくないので、役立つかもしれないと思いました):

#0  0xff15665c in _malloc_unlocked () from /lib/libc.so.1
#1  0xff15641c in malloc () from /lib/libc.so.1
#2  0xff1a8c80 in _findbuf () from /lib/libc.so.1
#3  0xff1a8f0c in _wrtchk () from /lib/libc.so.1
#4  0xff1ad834 in _fwrite_unlocked () from /lib/libc.so.1
#5  0xff1ad798 in fwrite () from /lib/libc.so.1
#6  0x000128ac in gaussian ()
#7  0x00010f78 in main ()

どんな助けでも大歓迎です!

4

3 に答える 3

4

問題はここにあります:

outfilename = (char *)malloc(FILENAME_MAX*sizeof(char));
outfilename = "file.txt";

そのような文字列を割り当てることはできません。使用する必要がありますstrcpy

strcpy(outfilename, "file.txt");

何が起こっているのかというoutfilenameと、文字列の割り当てでポインタを上書きしているということです。次に、それを解放しようとしますfree(outfilename);。文字列リテラルを解放しているため、動作は未定義であり、クラッシュが発生します。

なぜクラッシュするのか、他のケースではクラッシュしないのか。動作は定義されていないため、何でも発生する可能性があります。指数関数コードがスタック/ヒープに対して何かを実行し、クラッシュする/クラッシュしない原因となる可能性があります。

編集:タイプミスや誤植だといいのですが、どこoutfileが初期化されているかもわかりません。それが実際に初期化されない場合、それは別のエラーです。(そしておそらくあなたの特定のセグメンテーション違反を引き起こしているもの)

したがって、次のようになります。

FILE *outfile;
outfilename = (char *)malloc(FILENAME_MAX*sizeof(char));
strcpy(outfilename, "file.txt");

outfile = fopen(outfilename, "w");
if (outfile == NULL){
    //  Error, file cannot be openned.
}
于 2011-11-18T06:41:26.237 に答える
1

まず、すべての警告を有効にして、デバッグ情報を生成してコンパイルする必要があります。それはフラグをgcc意味します。-Wall -g

FILE *outfile;
outfilename = (char *)malloc(FILENAME_MAX*sizeof(char));
outfilename = "file.txt";

あなたは使うべきです、そして私は例えばstrdupへの呼び出しを見ませんfopen

 outfile = fopen(outfilename, "r");

そして、デバッガーgdb(またはおそらくそのdddグラフィカルフロントエンド)の使用法を学ぶ必要があります。

于 2011-11-18T06:43:55.673 に答える
1
outfilename = "file.txt";
/* snip */
free(outfilename);

から取り戻したものだけを解放できますmallocfree定数へのポインタを渡すことはできません!

于 2011-11-18T06:47:48.647 に答える