2017-12-25 29 views
-1

私は動的な文字列バッファにcharsを読み込むプログラムを持っています。文字列のサイズはわかりません。固定サイズの「十分に大きい」バッファーを設定するだけではないという要件があります。mallocの後にchar *を初期化する必要はありますか?

関連の機能は次のように機能します。

char* read_field(FILE* data) 
{ 
    int size = 8; 

    char *field = malloc(size); 
    if (field == NULL) 
     exit(1); 

    char *tmp = NULL; 
    int idx = 0; 
    int ch = EOF; 

    while (ch) { 
     ch = fgetc(data); 

     // Double size if full 
     if (size <= idx) { 
      size *= 2; 
      tmp = realloc(field, size); 
      if (!tmp) 
       exit(1); 
      field = tmp; 
     } 

     field[idx++] = ch; 

     // Relevant termination in my use case 
     if (ch == ';' || ch == '\n') 
      ch = 0; 
    } 

    printf("field: %s\n"); // value correct, but sometimes valgrind error 

    return field; // field is free'd by the caller 
} 

今、プログラムが動作するようだが、Valgrindはを通してそれを実行しているとき、私は、エラーUninitialised value was created by a heap allocationConditional jump or move depends on uninitialised value(s)を取得します。上記のコードのように、printfまたはstrlenのような関数を呼び出すと、これらのエラーが任意に(時には)表示されます。

この問題は、malloc/reallocの代わりにcallocを使用した場合にソートされますが、再割り当てプロセスが複雑になります。

プログラムが正常に動作してもValgrindのエラーは無視できますか?メモリをゼロに初期化しないとどういう意味ですか?これを無視できない場合は、それを整理するのに最適なデザインは何ですか?

+1

'printfの( "フィールド:%sの\ nを");'あなたはNULで終了する必要printf' 'に渡す前に、あなたの文字列を忘れてしまったUB – coderredoc

+0

です。 – Quentin

+0

こんにちは、はい、申し訳ありません、私はそれを試してみました - それを編集しました。 – alexcs

答えて

1

文字列の最後に文字列ターミネータを挿入する必要があります。

PS: あなたには、いくつかのメモリ使用のmemsetをクリアしたい場合は、それがサイクル

+0

はい - それについて申し訳ありません - 私はすでにそれを試して、私はそれを編集しました。しかし、valgrindのエラーは続きます。 memsetについて、すべてのmallocとreallocの後に 'memset(str、0、n)'を実行することをお勧めしますか? – alexcs

+0

これは文字列ターミネータであり、修正を修正して解決しました。 – alexcs

1

使用のcalloc、そのはるかに良いよりのmallocmemsetのよりも高速です。

char *string = calloc(100 , sizeof(char*)); 
// Calloc automatically fills the memory blocks 
// Its much faster than malloc and memset 
// In addition , only in C you don't need typecast for memory allocators 
関連する問題