Переназначение переменной указателя после ее освобождения

Является ли это законным? Можете ли вы присвоить ptr чему-то после его освобождения?

int * ptr = (int*) malloc(sizeof(int));
free(ptr);
ptr = (int *) malloc(sizeof(int));

Ответы

Ответ 1

Вы не переназначаете указатель после его освобождения, вы просто повторно используете переменную ptr. Это прекрасно.

Ответ 2

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

Тем не менее, да, (re) -ассортировка здесь прекрасна.

Собственно, формулировка вопроса

Можете ли вы назначить ptr чему-то после его освобождения?

должен читать

Можно ли назначить ptr с помощью после освобождения?

Угадайте, что назначение без free -ing также является законным согласно C, но оно создаст утечку памяти как побочный эффект, поскольку переменная ptr удерживала возвращаемое значение функции распределения памяти, и вам нужно освободить память, как только вы закончите, используя ее. Если вы повторно назначаете указатель, не сохраняя копию указателя, вы потеряете доступ к памяти, выделенной функцией распределителя, и не сможете использовать free() его.

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

int x = 5, y = 10;
int * p = &x;
//do something with p
p = &y; //this is fine, just a re-assignment.

Ответ 3

Да. он действителен на языке C.

Связанный вопрос для дополнительной информации: Повторное использование бесплатных указателей в C

Согласно cwe.mitre.org:

В этом сценарии рассматриваемая память выделяется другой указатель действительно в какой-то момент после его освобождения. Оригинал указатель на освобожденную память снова используется и указывает куда-то в рамках нового распределения. По мере изменения данных он развращает действительная используемая память; это приводит к undefined поведению в процессе.

Ответ 4

Является ли это законным? Можете ли вы присвоить ptr чему-то после его освобождения?

Да, это законно. ptr можно переназначить столько раз, сколько захотите. Освобождение этого указателя необязательно для его переназначения, например

int * ptr = malloc(sizeof(int));
int *temp_ptr = ptr;         // temp_ptr is pointing to the location ptr is pointing
ptr = malloc(sizeof(int));   // ptr points to new location.

Обратите внимание, что вы не должны указывать возвращаемое значение malloc.

Ответ 5

Можете ли вы назначить ptr чему-то после его освобождения?

int * ptr = (int*) malloc(sizeof(int)); /* line 1 */
free(ptr); /* line 2 */
ptr = (int *) malloc(sizeof(int)); /* line 3 */

Принимая ваш вопрос как:

"Является ли законным присваивать адрес свежей динамически выделенной памяти указателю (строка 3) после того, как память, указатель которой указана на предыдущее динамическое выделение (строка 1), была освобождена (строка 2)?"

Тогда этот ответ да.


Запуск строки 3 также будет действителен без выполнения строки 2. Тем не менее, если не вызывать free() (строка 2), значение, присвоенное ptr (строка 1), перезаписывается (строка 3), и с этим возможность вызывать free() на ptr начальное значение теряется, что в свою очередь оставляет программу утечкой именно этой памяти, выделенной изначально.

Ответ 6

Да, вы назначаете новую память в кучу и ее юридическую.

Я бы рекомендовал вместо этого использовать realloc.

В случае неудачи realloc() из , глава §7.22.3.5,

Функция realloc возвращает... нулевой указатель, если новый объект не может быть выделено.

и

[....] Если память для нового объекта не может быть выделена, старый объект не освобождается и его значение не изменяется.

Правильный способ использования realloc будет

ptr_new = realloc(ptr, sizeof(int)*2);
if (ptr_new == NULL)
{
    free(ptr);
}

Также, пожалуйста, прочитайте почему я не должен указывать возвращаемое значение malloc.

Ответ 7

Да. Это совершенно законно. ptr - автономная переменная, которая продолжает существовать независимо от ее содержимого. Ничего не происходит с местом памяти, где хранится ptr. Нет ничего, что помешало бы вам присвоить вам какую-либо ценность. Правильность распределения памяти (malloc/realloc и т.д.) - это другая история, но нет ничего плохого в повторном использовании переменной (ячейки памяти) для хранения адреса ячейки памяти.

Ответ 8

Когда вы объявляете указатель, ему будет выделено место памяти. Это местоположение можно переназначить.

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

Фактически, операционные системы, которые являются полезными программами, которые никогда не заканчиваются, все время переназначают некоторые фиксированные указатели на процессы, освобождают их при завершении процесса и т.д.

Программирование, в котором присвоения недопустимы, называется functional programming.