Почему моя реализация динамического массива строк утечки? - PullRequest
0 голосов
/ 24 октября 2011

Мне нужен массив строк, который динамически изменяет размер, когда к нему добавляется больше элементов. Я получил базовый код, работающий, но 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 и как я могу это исправить? Я хотел бы освободить каждую строку отдельно, а затем освободить структуру, но я чего-то упускаю.

Ответы [ 2 ]

5 голосов
/ 24 октября 2011

Вы освобождаете строки, содержащиеся в arr->items, но сами не освобождаете arr->items.(Вы выделили его в string_array_add).

0 голосов
/ 24 октября 2011

Проблема с этой строкой:

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

Вы перезаписываете старый указатель. Вам нужно перераспределить этот указатель, а не new_items.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...