Освободить память в c без использования функции free()

Я попытался освободить память без использования free(), как показано ниже.

int *ptr = malloc(20);
realloc(ptr, 0);

Это будет работать?


person amman059    schedule 16.02.2014    source источник
comment
Было бы лучше, если бы вы объяснили, почему вы не хотите использовать бесплатное... Вопрос интервью?   -  person    schedule 16.02.2014
comment
Пожалуйста, почему вопрос помечен recursion и marco?   -  person alk    schedule 16.02.2014


Ответы (4)


Стандарты языка C в этом отличаются: в C90 передача нулевого размера была такой же, как вызов free:

Если size равен нулю, память, ранее выделенная в ptr, освобождается, как если бы был сделан вызов free, и возвращается нулевой указатель.

Однако это изменилось в C99:

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

Обратите внимание, что освобождение больше не является обязательным требованием; ни один из них не возвращает NULL при передаче нулевого размера.

person Sergey Kalinichenko    schedule 16.02.2014
comment
+1 за изменение языка, я не заметил - person Ed S.; 16.02.2014
comment
+1. Я думаю, что резюме здесь таково: если вы хотите бесплатно, используйте free(), так как вы не можете полагаться на realloc(0). - person Oliver Charlesworth; 16.02.2014
comment
Аккуратный. И это снова меняется в C11. - person Kerrek SB; 16.02.2014
comment
Таким образом, вывод таков: это зависит от реализации библиотеки C в соответствии с комментариями каждого. - person amman059; 16.02.2014
comment
@ amman059 amman059 Как упоминал выше Оли Чарльзворт, самый безопасный подход — вызвать free, когда вы хотите освободить память. Другим следствием этого изменения является то, что если вы не уверены в версии языка C, с которой будет компилироваться ваш код, вам не следует вызывать realloc с нулевым размером. - person Sergey Kalinichenko; 16.02.2014
comment
@dasblinkenlight Согласен!! и спасибо за ваши предложения. - person amman059; 16.02.2014
comment
@ amman059 Добро пожаловать! Если вы найдете ответ полезным, подумайте о том, чтобы принять его, нажав на серую галочку рядом с ним. Это сообщит другим посетителям сайта, что вы больше не ищете улучшенное решение, и заработает значок при переполнении стека. - person Sergey Kalinichenko; 16.02.2014

realloc(ptr, 0) не эквивалентно free(ptr)

Стандарт C11 говорит:

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

Почему, потому что realloc делает ниже вещи,

  1. Он создает новую память указанного размера.
  2. Копирует содержимое из старой памяти в новую.
  3. Освобождает старую память
  4. Возвращает адрес новой памяти
person Sunil Bojanapally    schedule 16.02.2014
comment
На самом деле это говорит о том, что поведение передачи 0 определяется реализацией. - person Ed S.; 16.02.2014
comment
@ЭдС. Правда, его реализация определила. Ответ отредактирован. - person Sunil Bojanapally; 16.02.2014

Возможно, но рассчитывать на это нельзя. Из документов:

Если new_size равен нулю, поведение определяется реализацией (может быть возвращен нулевой указатель или может быть возвращен ненулевой указатель, который нельзя использовать для доступа к хранилищу).

person Ed S.    schedule 16.02.2014
comment
Из справочных страниц: если размер равен нулю, а ptr не равен NULL, то вызов эквивалентен free(ptr) - person delannoyk; 16.02.2014
comment
@delannoyk: справочная страница Linux не является стандартом C. Я изменил то, что у меня было изначально, хотя заранее не знал об этом поведении. Узнал что-то новое. - person Ed S.; 16.02.2014

По крайней мере, для POSIX: realloc(p, 0) не совпадает с free(p).

Из текущей документации POSIX для realloc():

Предыдущие версии явно разрешали вызов realloc (p, 0) для освобождения пространства, на которое указывает p, и возврата нулевого указателя. Хотя такое поведение можно интерпретировать как разрешенное данной версией стандарта, комитет по языку C указал, что такая интерпретация неверна.

person alk    schedule 16.02.2014