Вопрос на C: однократное разыменование для пустого ** двойного указателя косвенного обращения

Я получил это сообщение:

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, я мог бы лучше реализовать в функции.

Спасибо всем за хорошее обсуждение.

6
задан Community 23 May 2017 в 11:55
поделиться