- ベストアンサー
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; }
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
> if(NULL == ((char *)realloc(str,len))){ realloc は失敗したときに確かにNULLを返しますが、 成功したときは新しい領域へのポインタを返します。 ですからその値を何らかの変数で受けてやらなければなりません。 よくあるのはいったん別の一時的なポインタ変数に受けて、NULLチェックを 通ったらポインタを更新というやり方ですね。 char *p; p = realloc(str, len); if (!p) エラー else str = p; // 新しい領域を指すように更新
その他の回答 (1)
- venzou
- ベストアンサー率71% (311/435)
幾つか問題があります。 ソースの途中から //領域を初期化 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; }
お礼
お礼が遅くなり申し訳ありません >>//memset(str,'\0',sizeof(str)); 危険 sizeof(str) = 4 ですよ そうですね。ありがとうございます。 >>len += strlen(tmp); //正しいサイズを足しましょう 投稿直後に気づきました。これじゃあ意味ないですもんね。 >>if(NULL == (str = (char *)realloc(str,len))){ //strに代入が必要 #1の方にもご指摘を頂きました。これが原因でしたね。
お礼
お礼が遅くなり申し訳ありません そうですね。 戻り値を受け取らないとダメですね。 ありがとうございます。