Deallocationg char ** внутри структуры - PullRequest
0 голосов
/ 15 мая 2019

Эта проблема похожа на мою.
Но не предоставьте мне решения.

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

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

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

Вот код:

Объявление списка:

typedef struct {
    char** storage;
} List;

Main:

int main(){
    int size = 2;
    List* list;
    list = new_list(2);
    add(list, "Hello", 0);
    add(list, "World", 1);
    printf("\nlist->storage[0]: %s", list->storage[0]);
    printf("\nlist->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])'.
Цель состоит в том, чтобы удалить все выделенныеstring.
Если в списке нет членов, значит, код, запущенный не в цикле for, и функция 'delte_list' работают хорошо.

Так что это мой туманв строке: 'free ((* list) -> storage [a])'

1 Ответ

1 голос
/ 15 мая 2019

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...