Я недавно обнаружил __attribute__((cleanup))
, что очень удобно.Я сделал универсальную функцию, чтобы освободить любой тип указателя, и она отлично работает.
#define _autofree_ __attribute__ ((cleanup(free_pointer)))
...
void free_pointer(void *pointer)
{
free(*(void **) pointer);
}
Но это не так просто, когда дело доходит до освобождения 2D-массивов.Насколько я знаю, очистка использует указатель на данный указатель для ограничения стека, и это хорошо, потому что она не использует копию в любой точке.В любом случае, разыменование (void **)
приведения для прохождения ошибок «разыменование void *» работает, но тогда, если я делаю
#define _autofree2d_ __attribute__ ((cleanup(free_pointer_array)))
...
void free_pointer_array(void *pointer_array)
{
for (size_t i = 0 ; (void **) pointer_array[i] ; ++i)
free(*(void **) pointer_array[i]);
free(*(void ***) pointer_array);
}
, я получаю разыменование void * из-за скобок [i]
.Кроме того, это просто не выглядит правильно.
Я также пытаюсь сделать это менее универсальным способом, используя указатели на символы (как я сейчас работаю с массивом слов), и он компилируется, но дает нам segfaultиз-за недействительного свободного.
void free_pointer_array(char ***array)
{
for (size_t i = 0 ; *array[i] ; ++i)
free(*array[i]);
free(**array); // Tried using ***array and got
// "pointer from integer without a cast" error
}