Я получил это сообщение:
expected 'void **' but argument is of type 'char **'
когда я попытался скомпилировать что-то похожее на это:
void myfree( void **v )
{
if( !v || !*v )
return;
free( *v );
*v = NULL;
return;
}
Я нашел то, что я считаю решением, после прочтения этого вопроса о переполнении стека:
Избегайте предупреждения о несовместимости указателя при работе с двойным косвенным обращением - Stack Overflow
Итак, я настроился примерно так:
#include
#include
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? Я разыменовываю указатель void, не так ли?
Спасибо, ребята
РЕДАКТИРОВАТЬ 10.12.2010 16:45 EST:
Как было указано, free (NULL)
безопасен и покрывается стандартом C. Кроме того, как обсуждается ниже, мой приведенный выше пример не является законным C. См. Ответ caf, ответ Зака и мой собственный ответ.
Поэтому мне будет проще инициализировать любые указатели to-be-malloc'd как NULL и затем позже просто free () и NULL прямо в коде:
free( pointer );
pointer = NULL;
Причина, по которой я проверял NULL в myfree (), как я это делал, заключалась в моем опыте работы с fclose (). fclose (NULL)
может segfault в зависимости от платформы (например, xpsp3 msvcrt.dll 7.0.2600.5512), поэтому я предположил (ошибочно) то же самое может произойти с free (). Я решил, что вместо того, чтобы загромождать свой код операторами if, я мог бы лучше реализовать в функции.
Спасибо всем за хорошее обсуждение.