Свободно ли (ptr) где ptr NULL повреждена память?

Теоретически я могу сказать, что

free(ptr);
free(ptr); 

это повреждение памяти, так как мы освобождаем память, которая уже была освобождена.

Но что, если

free(ptr);
ptr=NULL;
free(ptr); 

Поскольку ОС будет вести себя неопределенным образом, я не могу получить теоретический анализ того, что происходит. Что бы я ни делал, это повреждение памяти или нет?

Допустимо ли освобождение указателя NULL?

11 ответов

Решение

7.20.3.2 free функция

конспект

#include <stdlib.h> 
void free(void *ptr); 

Описание

free Функция вызывает пространство, на которое указывает ptr быть освобожденным, то есть предоставленным для дальнейшего распределения. Если ptr нулевой указатель, никаких действий не происходит.

См. ISO-IEC 9899.

При этом, глядя на различные кодовые базы в дикой природе, вы заметите, что люди иногда делают:

if (ptr)
  free(ptr);

Это связано с тем, что некоторые среды выполнения C (я точно помню, что это было на PalmOS) зависали при освобождении NULL указатель.

Но в настоящее время я считаю, что можно предположить, free(NULL) это не в соответствии с инструкциями стандарта.

Все совместимые со стандартами версии библиотеки C рассматривают бесплатные (NULL) как неактивные.

Тем не менее, в свое время было несколько версий free, которые могли бы потерпеть крах на free(NULL), поэтому вы можете увидеть, что некоторые методы защитного программирования рекомендуют:

if (ptr != NULL)
    free(ptr);

Если ptr равен NULL, никакие операции не выполняются.

говорит документация.

Я помню, как работал над PalmOS, где free(NULL) разбился.

free(ptr);
ptr=NULL;
free(ptr);/*This is perfectly safe */

Вы можете безопасно удалить пустой указатель. В этом случае никакие операции выполняться не будут. Другими словами, free() ничего не делает с указателем NULL.

Рекомендуемое использование:

free(ptr);
ptr = NULL;

Увидеть:

man free

     The free() function deallocates the memory allocation pointed to by ptr.
     If ptr is a NULL pointer, no operation is performed.

Когда вы установите указатель на NULL после free() ты можешь позвонить free() снова и никакая операция не будет выполнена.

free(NULL) совершенно законно в C, а также delete (void *)0 а также delete[] (void *)0 законны в C++.

Кстати, освобождение памяти дважды обычно приводит к некоторой ошибке во время выполнения, поэтому она ничего не портит.

free(ptr) - это сохранение в C, если ptr равно NULL, однако большинство людей не знают, что NULL не обязательно должен быть равен 0. У меня есть хороший пример старой школы: на C64, по адресу 0, есть такое IO-порт Если вы написали программу на C, обращающуюся к этому порту, вам понадобится указатель, значение которого равно 0. Тогда отвечающая за ядро ​​библиотека c должна будет различать 0 и NULL.

С уважением

Не повреждение памяти, но поведение зависит от реализации. По стандарту это должен быть юридический код.

Хотя в настоящее время это безопасно, я всегда использую следующий макрос для освобождения указателей:

      #define FREE(ptr)      \ 
{                      \
    if ((ptr) != NULL) \
    {                  \
        free(ptr);     \
        (ptr) = NULL;  \
    }                  \
}

ptr указывает на какую-то область памяти, скажем, 0x100.

Когда вы освобождаете (ptr), в основном вы разрешаете диспетчеру памяти использовать 0x100 для другой деятельности или процесса, и, проще говоря, это освобождение ресурсов.

Когда вы делаете ptr=NULL, вы делаете ptr указателем на новое местоположение (давайте не будем беспокоиться о том, что такое NULL). Делая это, вы потеряли отслеживание данных памяти 0x100. Это то, что утечка памяти.

Поэтому не рекомендуется использовать ptr = NULL для правильного ptr.

Вместо этого вы можете сделать некоторые безопасные проверки с помощью:

if (ptr! = NULL) {free (ptr);}

Когда вы освобождаете (ptr), где ptr уже указывает на NULL, он не выполняет никаких операций. Так что это безопасно.

Другие вопросы по тегам