• ベストアンサー

reallocについて

現在、領域を拡張しながら、 ファイルを読み込んで呼び元に返却するPGを作成しています。 reallocがうまくいかないので、試しに小さいのを作って みましたが、これだとreallocの2度目で落ちます。 100文字ずつ呼んでいるので、拡張も100文字ずつ行っています。 メモリ確保に失敗なら、まだ分かるのですが、 ちょっと理由がわかりません。 reallocを複数繰り返していることも問題だと思いますが、 まずは正常に処理を流したいと考えています。 よろしくお願いします。 ~~~~~~ソース~~~~~~~~ //ファイルを読み込んでから領域を確保する #include <stdio.h> #include <string.h> #include <stdlib.h> #define BUFF 100 int main() { FILE *fp; char tmp[BUFF+1]; char *str; int len = 0; fp = fopen( "c:/test.txt" , "rb" ); if(fp ==0){ printf("ファイルがありません\n"); return -1; } //領域を初期化 str = (char *)malloc(1); memset(str,'\0',sizeof(str)); while(feof(fp)==0){ memset(tmp,'\0',sizeof(tmp)); fgets(tmp,BUFF,fp); //領域を再確保 len += BUFF+1; if(NULL == ((char *)realloc(str,len))){ printf("メモリ確保エラー"); } //読み込んだ値を変数に追加 strcat(str,tmp); } printf("文字列\n\n%s\n",str); printf("長さ:%d\n",len); fclose(fp); return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

> if(NULL == ((char *)realloc(str,len))){ realloc は失敗したときに確かにNULLを返しますが、 成功したときは新しい領域へのポインタを返します。 ですからその値を何らかの変数で受けてやらなければなりません。 よくあるのはいったん別の一時的なポインタ変数に受けて、NULLチェックを 通ったらポインタを更新というやり方ですね。 char *p; p = realloc(str, len); if (!p) エラー else str = p; // 新しい領域を指すように更新

derby
質問者

お礼

お礼が遅くなり申し訳ありません そうですね。 戻り値を受け取らないとダメですね。 ありがとうございます。

すると、全ての回答が全文表示されます。

その他の回答 (1)

  • venzou
  • ベストアンサー率71% (311/435)
回答No.2

幾つか問題があります。 ソースの途中から //領域を初期化 str = (char *)malloc(1); //memset(str,'\0',sizeof(str)); 危険 sizeof(str) = 4 ですよ memset(str,'\0',1); len = 1; //現在のサイズ while(feof(fp)==0){ // memset(tmp,'\0',sizeof(tmp)); 初期化不要 fgets(tmp,BUFF,fp); //改行までしか読みません //領域を再確保 len += strlen(tmp); //正しいサイズを足しましょう if(NULL == (str = (char *)realloc(str,len))){ //strに代入が必要 printf("メモリ確保エラー"); return -1; //終了しましょう } //読み込んだ値を変数に追加 strcat(str,tmp); } printf("文字列\n\n%s\n",str); printf("文字列の長さ  :%d\n",strlen(str)); printf("バッファのサイズ:%d\n",len); fclose(fp); return 0; }

derby
質問者

お礼

お礼が遅くなり申し訳ありません >>//memset(str,'\0',sizeof(str)); 危険 sizeof(str) = 4 ですよ そうですね。ありがとうございます。 >>len += strlen(tmp); //正しいサイズを足しましょう 投稿直後に気づきました。これじゃあ意味ないですもんね。 >>if(NULL == (str = (char *)realloc(str,len))){ //strに代入が必要 #1の方にもご指摘を頂きました。これが原因でしたね。

すると、全ての回答が全文表示されます。
ユーザー登録人数について
このQ&Aのポイント
  • ScanSnap Homeの液晶ディスプレイには何人までユーザーが登録できるのか?
  • 購入前に知りたいことのひとつが、ScanSnap Homeの液晶ディスプレイに登録できるユーザー数です。
  • 職員全員の登録が可能なのか、登録人数に制限はあるのか知りたいです。
回答を見る

専門家に質問してみよう