2011-10-24 10 views
0

もっと多くの項目が追加されると動的にサイズ変更される文字列配列が必要です。基本的なコードは動作していますが、valgrindはメモリリークを報告します。動的文字列配列の実装がなぜ漏れていますか?

静的および動的に割り当てられた文字列で動作するはずの実装は次のようになります。

typedef struct { 
    char **items; 
    int num; 
} StringArray; 

StringArray* string_array_init() { 
    StringArray *arr = malloc(sizeof(StringArray)); 
    arr->items = NULL; 
    arr->num = 0; 
    return arr; 
} 

void string_array_add(StringArray *arr, char *str, int str_len) { 
    void *new_items = realloc(arr->items, (arr->num + 1) * sizeof(char *)); 

    arr->items = (char**)new_items; 
    arr->items[arr->num] = strndup(str, str_len); 
    arr->num++; 
} 

void string_array_cleanup(StringArray *arr) { 
    int i; 

    for (i = 0; i < arr->num ; i++) { 
     free(arr->items[i]); 
    } 

    free(arr); 
} 




int main() { 
    StringArray *arr = string_array_init(); 

    string_array_add(arr, "item 1", strlen("item 1")); 
    string_array_add(arr, "item 2", strlen("item 2")); 
    string_array_add(arr, "item 3", strlen("item 3")); 

    string_array_cleanup(arr); 

    return 0; 
} 

Valgrindのレポート:

==31443== HEAP SUMMARY: 
==31443==  in use at exit: 12 bytes in 1 blocks 
==31443== total heap usage: 7 allocs, 6 frees, 53 bytes allocated 
==31443== 
==31443== 12 bytes in 1 blocks are definitely lost in loss record 1 of 1 
==31443== at 0x4025CCD: realloc (vg_replace_malloc.c:525) 
==31443== by 0x80484A6: string_array_add (in ...) 
==31443== by 0x8048593: main (in ...) 
==31443== 
==31443== LEAK SUMMARY: 
==31443== definitely lost: 12 bytes in 1 blocks 
==31443== indirectly lost: 0 bytes in 0 blocks 
==31443==  possibly lost: 0 bytes in 0 blocks 
==31443== still reachable: 0 bytes in 0 blocks 
==31443==   suppressed: 0 bytes in 0 blocks 
==31443== 

なぜreallocの漏れとどのように私はそれを修正することができますがありますか?私は別々にすべての文字列を解放し、構造体を解放すれば十分ですが、何かが欠けています。

+0

追加: 'new_items'を' void * 'から明示的にキャスティングするのではなく、最初から' char ** 'にする方がより良いスタイルとみなされます。そうすれば、コンパイラは暗黙的なキャストを行い、型チェックをより良く行うことができます。 –

答えて

5

arr->itemsに含まれる文字列を解放しますが、arr->items自体を解放しないでください。 (あなたはstring_array_addにそれを割り当てました)。

+0

まあ...ええと...ええ...腹を立てる* gg *あなたが正しいです、ありがとう! – Max

-1

問題は、この行を次のとおりです。

arr->items = (char**)new_items; 

あなたは古いポインタを上書きします。 new_itemsではなく、このポインタを再割り当てする必要があります。

+0

それはまさに彼が1行上のことです。 – wormsparty

関連する問題