もっと多くの項目が追加されると動的にサイズ変更される文字列配列が必要です。基本的なコードは動作していますが、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の漏れとどのように私はそれを修正することができますがありますか?私は別々にすべての文字列を解放し、構造体を解放すれば十分ですが、何かが欠けています。
追加: 'new_items'を' void * 'から明示的にキャスティングするのではなく、最初から' char ** 'にする方がより良いスタイルとみなされます。そうすれば、コンパイラは暗黙的なキャストを行い、型チェックをより良く行うことができます。 –