Установка переменной в NULL после освобождения - PullRequest
141 голосов
/ 22 июня 2009

В моей компании есть правило кодирования, которое гласит, что после освобождения памяти сбросьте переменную в NULL. Например ...

void some_func () 
{
    int *nPtr;

    nPtr = malloc (100);

    free (nPtr);
    nPtr = NULL;

    return;
}

Мне кажется, что в случаях, подобных приведенному выше, установка значения NULL не имеет никакого значения. Или я что-то упустил?

Если в таких случаях нет смысла, я собираюсь обсудить это с «командой качества», чтобы удалить это правило кодирования. Пожалуйста, совет.

Ответы [ 23 ]

1 голос
/ 03 сентября 2016

Всегда желательно объявить переменную-указатель с NULL , например,

int *ptr = NULL;

Скажем, ptr указывает на 0x1000 адрес памяти. После использования free(ptr) всегда желательно обнулить переменную-указатель, объявив снова NULL . e.g.:

free(ptr);
ptr = NULL;

Если не объявлено повторно в NULL , переменная-указатель продолжает указывать на тот же адрес ( 0x1000 ), эта переменная-указатель называется висячий указатель . Если вы определите другую переменную-указатель (скажем, q ) и динамически назначите адрес новому указателю, есть шанс получить тот же адрес ( 0x1000 ) новой переменной-указателем. Если в этом случае вы используете один и тот же указатель ( ptr ) и обновите значение по адресу, указанному тем же указателем ( ptr ), то программа завершит запись значения в место, куда указывает q (поскольку p и q указывают на один и тот же адрес ( 0x1000 )).

* * +1039 например,
*ptr = 20; //Points to 0x1000
free(ptr);
int *q = (int *)malloc(sizeof(int) * 2); //Points to 0x1000
*ptr = 30; //Since ptr and q are pointing to the same address, so the value of the address to which q is pointing would also change.
1 голос
/ 24 февраля 2017

Короче говоря: вы не хотите случайно (по ошибке) получить доступ к адресу, который вы освободили. Потому что, когда вы освобождаете адрес, вы разрешаете ему выделять этот адрес в куче другому приложению.

Однако, если вы не установите указатель на NULL и по ошибке попытаетесь отменить ссылку на указатель или изменить значение этого адреса; ВЫ МОЖЕТЕ ЕЩЕ ДЕЛАТЬ. НО ЧТО-ТО, ЧТО ВЫ ЛОГИЧЕСКИ ХОТИТЕ СДЕЛАТЬ.

Почему я все еще могу получить доступ к памяти, которую я освободил? Потому что: возможно, вы освободили память, но переменная-указатель все еще содержала информацию об адресе кучи памяти. Итак, в качестве защитной стратегии, пожалуйста, установите ее в NULL.

1 голос
/ 10 апреля 2011

Поскольку у вас есть команда по обеспечению качества, позвольте мне добавить небольшое замечание о QA. Некоторые автоматизированные инструменты QA для C помечают назначения для освобожденных указателей как «бесполезное назначение для ptr». Например, PC-lint / FlexeLint от Gimpel Software сообщает tst.c 8 Warning 438: Last value assigned to variable 'nPtr' (defined at line 5) not used

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

...