освободить память по двойному указателю

0
//char char **p; declared in .h file
size_t bs = 5;
size_t Size = sizeof(obj);
p = (char**)malloc(bs);
for (size_t i = 0; i < bs;i++){p[i] = (char*)malloc(Size);}

for (size_t j = 0; j < bs-1; j ++){p[j] = &(p[j + 1][0]); }

for (size_t i = 0; i < bs; i++){free(p[i]);}

free(p);

мой код останавливается при попытке освободить последний элемент p в цикле for. Кто-нибудь, что я могу сделать неправильно?

EDIT: У меня все еще есть такая же проблема, даже когда вы меняете ее на (char *) malloc (bs sizeof (char *));

это все еще не работает:

size_t bs = 5;
size_t Size = sizeof(obj);
p = (char**)malloc(bs* sizeof(char *));
for (size_t i = 0; i < bs;i++){p[i] = (char*)malloc(Size);}
for (size_t j = 0; j < bs-1; j ++){p[j] = &(p[j + 1][0]); }
for (size_t i = 0; i < bs; i++){free(p[i]);}
free(p);

использование нового вместо malloc не решает проблему

Однако этот код освобождает память.

size_t bs = 5;
size_t Size = sizeof(obj);
p = (char**)malloc(bs* sizeof(char *));
for (size_t i = 0; i < bs;i++){p[i] = (char*)malloc(Size);}
for (size_t i = 0; i < bs; i++){free(p[i]);}
free(p);

поэтому проблема кажется чем-то с этой частью кода

for(size_t j = 0; j < bs-1; j ++){p[j] = &(p[j + 1][0]); }

Я хочу, чтобы это был неявный связанный список, кто-нибудь знает, что я делаю неправильно?

  • 3
    Почему тег C ++ при использовании malloc ?
  • 0
    Это C или C ++? Я полагаю, что это справедливо в любом случае, но, возможно, выберите только один.
Показать ещё 9 комментариев
Теги:
malloc
free
double-pointer

3 ответа

2

Вы не выделяете достаточно места для указателей. Изменить на

p = malloc(bs * sizeof(char*));
  • 0
    Это одна из причин, почему C ++ лучше. Было бы выделено правильное количество с new .
  • 1
    @Mark: Полагаю, вы хотели сказать «почему оператор C ++ new[] лучше»? malloc работает точно так же в C ++, а функции размещения C ++, такие как ::operator new() также требуют количества байтов.
1

Проблема в том, что вы:

  • выделить массив из 5 указателей
  • выделить 5 массивов символов и сохранить их в этом первом массиве
  • переместите эти указатели вниз в массив, перезапишив (и проиграв) первый указатель и дублируя последний
  • попытайтесь освободить 5 указателей в массиве.

Итак, на этом последнем шаге вы дважды освобождаете указатель (поскольку последние две записи в p[3] и p[4] одинаковы), вызывая неопределенное поведение.

Вы говорите, что хотите "неявный связанный список", подразумевая, что вы пытаетесь наложить указатели на объекты (а не на массив верхнего уровня, как вы это делаете), и в этом случае вам нужно что-то вроде:

for(size_t j = 0; j < bs-1; j ++) { *(char **)p[j] = p[j + 1]); }
*(char **)p[bs-1] = 0;  // null terminate the linked list

это предполагает, что obj определяется примерно так:

struct obj {
    struct obj *next;
    // more fields
1

На первом malloc вам не нужно 5 байт, но в 5 раз указатель.

p = (char**)malloc(bs * sizeof(char *));
  • 0
    хорошо, я изменил его на (char **) malloc (bs * sizeof (char *)); это все еще дает мне ту же проблему.
  • 1
    Это правда, но утечка не подходит для этого. Это на самом деле переполнение, потому что элементы после конца доступны.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню