Deallocationg char ** внутри структуры


Но не доставляй мне решения.

Это всего лишь упрощенный код для тестирования и лучшего понимания.
Я знаю, что этот код не заботится о проблемах после функций malloc.

Код предназначен для сохранения слов в структуре с именем List в хранилище char **, которое используется в качестве массива.

Для создания списка и добавления элемента отлично работает.
Но удаление списка создает проблемы.

Вот код:

Декларация списка:

typedef struct {
    char** storage;
} List;

Главный:

int main(){
    int size = 2;
    List* list;
    list = new_list(2);
    add(list, "Hello", 0);
    add(list, "World", 1);
    printf("
list->storage[0]: %s", list->storage[0]);
    printf("
list->storage[1]: %s",  list->storage[1]);

    delete_list(&list,size);

    return 0;
}

Составьте новый список:

List* new_list(size) {
    List* listptr = malloc(sizeof(List));
    listptr->storage = (char**)malloc(size * sizeof(char));
    return listptr;
}

Добавьте строку в список:

void add(List* list, char* string, int pos) {
    list->storage[pos] = (char*)malloc(strlen(string) * sizeof(char));
    list->storage[pos] = string;
}

Удалить список со всеми участниками:

void delete_list(List** list, int size) {
    int a = 0;
    for (a = 0; a < size; a++)
        free((*list)->storage[a]);

    free((*list)->storage);
    free(*list);
}

Здесь я получаю сообщение об ошибке в цикле for в строке 'free ((* list) -> storage [a])'.
Цель состоит в том, чтобы удалить каждую выделенную строку.
Если в списке нет членов, значит, код запускается не в цикле for, а функция 'delte_list' работает хорошо.

Так что это моя ошибка в строке: 'free ((* list) -> storage [a])'

Всего 1 ответ


Это распределение неверно:

listptr->storage = (char**)malloc(size * sizeof(char));
                                                ^^^^^

Поскольку storage - это char** размер должен быть sizeof(char*) . Когда вы используете только sizeof(char) вас заканчивается слишком мало памяти, а позже вы пишете за пределы выделенной памяти.

Также эта строка:

list->storage[pos] = string;

кажется неправильно.

Здесь вам, вероятно, понадобится такой strcpy :

strcpy(list->storage[pos], string)

а также добавить 1 к malloc для завершения строки, т.е.

malloc((1 + strlen(string)) * sizeof(char));

но обратите внимание, что sizeof(char) всегда равен 1, поэтому

malloc(1 + strlen(string));

Это хорошо.

КСТАТИ: Хороший способ исправить ваш malloc - это использовать sizeof what_the_variable_points_to. Подобно:

char** x = malloc(size * sizeof *x);
                                ^^
                        Use *x instead of sizeof(char*)

таким образом вы всегда получаете правильный размер и избегаете ошибок из-за простых опечаток.

Как пример из вашего кода:

List* listptr = malloc(sizeof(List));     // works but
List* listptr = malloc(sizeof *listptr);  // this is less error prone

Есть идеи?

10000