косвенного Я получил это сообщение:C вопрос: одиночные разыменовать на ничтожный ** двойного указателя
expected 'void **' but argument is of type 'char **'
, когда я пытался собрать что-то похожее на это:
void myfree(void **v)
{
if(!v || !*v)
return;
free(*v);
*v = NULL;
return;
}
Я нашел что я думаю, это решение после прочтения этого вопроса о переполнении стека:
Avoid incompatible pointer warning when dealing with double-indirection - Stack Overflow
Так я приспособил к чему-то вроде этого:
#include <stdio.h>
#include <stdlib.h>
void myfree(void *x)
{
void **v = x;
if(!v || !*v)
return;
free(*v);
*v = NULL;
return;
}
int main(int argc, char *argv[])
{
char *test;
if((test = malloc(1)))
{
printf("before: %p\n", test);
myfree(&test);
printf("after: %p\n", test);
}
return 0;
}
Законно ли это C? Я разыскиваю указатель на пустоту, не так ли?
Спасибо, ребята
EDIT 12/10/2010 4:45 вечера EST:
Как уже было отмечено, free(NULL)
безопасен и покрыт стандартом C. Кроме того, как обсуждалось ниже, мой пример выше не является законным C. См. Ответ в кафе, ответ Зака и мой собственный ответ.
Поэтому это будет легче для меня, чтобы инициализировать любые чтобы быть-malloc'd указатели как NULL, а затем в дальнейшем просто бесплатно() и NULL непосредственно в коде:
free(pointer);
pointer = NULL;
Причина, по которой я проверял NULL в myfree(), как и я, был из-за моего опыта работы с fclose(). fclose(NULL)
может segfault в зависимости от платформы (например, xpsp3 msvcrt.dll 7.0.2600.5512), и поэтому я предположил (ошибочно) то же самое может случиться со свободным(). Я вычислил, а не загромождал свой код, если бы я мог лучше реализовать функцию.
Спасибо всем за все хорошее обсуждение
Некоторые будут называть меня язычником, но я бы просто использовать `определить MyFree (х) делать {свободный (х); x = NULL} while (0) ` – 2010-12-06 22:06:13
Вы не разыскиваете« указатель на void ». Вы разыскиваете «указатель на указатель на void», который является совершенно законным. – aschepler 2010-12-06 22:12:28
На самом деле, я хочу исправить свой предыдущий макрос: `#define myfree (x) do {void ** tmp_ = & x; бесплатно (* tmp_); * tmp_ = NULL; } while (0) `(я думал, что не было возможности избежать двойной оценки` x`, но есть!) – 2010-12-06 22:19:18