- ベストアンサー
ファイルサイズの取得について
2つのテキストファイルのサイズを取得し、そのファイルサイズ分だけを動的にメモリを確保しようとしています。 int *c,*a;と宣言し、 fp=fopen("./data/Problem.txt","r");//1つ目のファイル fseek(fp, 0, SEEK_END); /* ファイルの終端までシーク */ size = ftell(fp); /* 終端の位置、すなわちファイルサイズを得る */ fseek(fp, 0, SEEK_SET); /* ファイルの先頭に戻る */ c = (int *)malloc(size); /* ファイルサイズ分メモリ確保 */ while((x=fgetc(fp))!=EOF){ c[i]=x; i++; } c[i]='\0'; i=0; fclose(fp); fpa=fopen("./data/Answer.txt","r");//2つ目のファイル fseek(fpa, 0, SEEK_END); size = ftell(fpa); fseek(fpa, 0, SEEK_SET); a = (int *)malloc(size); while((x=fgetc(fpa))!=EOF){ a[n]=x; n++; } a[n]='\0';//・・・・(1) n=0; fclose(fpa); とすると1つ目のファイルの方だけはうまくいくのですが、(1)の部分で 「sample.exeの0x00411dcでハンドルされていない例外が発生しました:0xc0000005:場所0x0000000に書き込み中にアクセス違反が発生しました。。」 というエラーが出ます。 また、 int *c,*a;を int *c,a[300]; のように片方を配列として宣言し、 //a = (int *)malloc(size); /* ファイルサイズ分メモリ確保 */ のようにコメントアウトすると上記のエラーは出ずにcにメモリは確保されているようです。 これは何故なのでしょうか? また、どうすればaとcでメモリを確保出来るようになるのでしょうか? よろしくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
int型でn個の配列が必要なのであれば、 malloc(sizeof(int)*n) としなければなりません。 int型のサイズは2または4バイトです。 malxさんのソースでは、 malloc(size); でsizeバイトのメモリ領域を取得して、 size×2バイトまたはsize×4バイトの領域に アクセスしようとされていたので アクセス違反になったわけです。 また、文字列の末尾にはヌル文字'\0'が ほとんどの場合必要である事、ftell()の 戻り値=ファイルサイズに不安がある事から、 さらに2バイトは多めに領域取得しておいた方が 安心かと思います。
その他の回答 (2)
- Herolin
- ベストアンサー率100% (2/2)
ヌル文字'\0'の追加は既にされていましたね。 すいません。 先程の補足ですが、fseek()後のftell()が 正確にファイルサイズを返す事と、 1文字ずつfgetc()した場合の繰り返し回数も ファイルサイズと一致する事、この2つを 様々な入力ファイル(例えばEOF文字の有無とか)で 検証された方が良いかと思います。
お礼
アドバイスありがとうございました。 お陰様で問題は解決出来ました。
- nitscape
- ベストアンサー率30% (275/909)
a[n]='\0';//・・・・(1) の部分にデバッグポイントを置いて、これをするときのnの値とsizeの値を見てはどうでしょうか? おそらくnの部分ではn=sizeとなっていると思います。メモリ確保が a = (int *)malloc(size); のため、(1)で代入するときには確保されていないメモリに書き込んでいるのではないでしょうか?
お礼
仰る通りn=sizeでした。 問題は解決出来ました。 御回答ありがとうございました。
お礼
malloc(sizeof(int)*n)の形で書くと問題なく動いてくれました。 御回答ありがとうございました。