Освобождение выделенной памяти массива нулевой длины в C - PullRequest
4 голосов
/ 01 декабря 2011

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

Их использование отлично работает;потом я вспомнил, что мне нужно освободить свою выделенную память, поэтому я просто выбросил свободную (struct);там, но, к моему ужасу, это привело меня к ошибке:

    *** glibc detected *** ./program: free(): invalid next size (fast): <address>
    ======= Backtrace: =========
     <omitted>
    ======= Memory Map: ========
     <omitted>

Вот простой пример плохо отформатированного кода:

   struct Stuff {
     int size; // defines the amount of bytes the entire struct will take up
     char data[0];
   }

   ...

   // This gives me an int and a char[30].
   struct Stuff *ptr = (struct Stuff *) malloc(sizeof(struct Stuff) + 30); 

   ... 
   doStuff();
   ...

   free(ptr);

И я получаю ошибку бесплатно);

Есть идеи?

Ответы [ 4 ]

6 голосов
/ 01 декабря 2011

Ваш код malloc() / free() в порядке.Для проверки закомментируйте все, что находится между malloc() и free(), и посмотрите, исчезнет ли проблема (держу пари, что это так).

Вы почти наверняка напишите где-нибудь за концом выделенной памятивозможно в doStuff()).Например, если doStuff() использует ptr->size для определения размера ptr->data, убедитесь, что ptr->size правильно инициализирован.

1 голос
/ 01 декабря 2011

Может быть, ваш код где-то меняет значение ptr.

Используйте:

struct Stuff * const ptr = ...

Вместо:

struct Stuff * ptr = ...

Для обнаружения проблем такого типа ввремя компиляции.

1 голос
/ 01 декабря 2011

Удалите doStuff (), просто оставив свободным (ptr), и повторите попытку.У вас такая же ошибка?

0 голосов
/ 01 декабря 2011

Вероятно, все, что вы делаете в doStuff(), использует более 30 дополнительных байтов, которые вы выделили за пределы заголовка структуры. Убедитесь, что вы правильно рассчитываете необходимое пространство.

...