2014-02-10 3 views
11

поэтому у меня есть часть памяти, выделенная malloc() и измененная позже с realloc().Освобождение выделенной памяти: realloc() vs. free()

В какой-то момент в моем коде я хочу его опорожнить, я имею в виду, по существу, дать ему память 0. Что-то, что интуитивно было бы сделано с realloc(pointer,0). Я читал здесь, что это реализация определена и не должна использоваться.

Должен ли я использовать free(), а затем сделать еще malloc()?

+9

Что вы подразумеваете под «пустым»? –

ответ

12

Это зависит от того, что вы имеете в виду: если вы хотите пустой памяти, используемой, но по-прежнему имеют доступ к этой памяти, то вы используете memset(pointer, 0, mem_size);, чтобы повторно инициализировать указанную память на нулях.
Если вам больше не нужна эта память, вы просто вызываете free(pointer);, что освободит память, поэтому ее можно использовать в другом месте.

Использование realloc(pointer, 0) может работать как free на вашей системе, но это не стандартное поведение. realloc(ptr, 0) не указывается стандартами C99 или C11 как эквивалент free(ptr).

realloc(pointer, 0) не соответствует free(pointer).

Стандарт (C99, §7.22.3.5):

 
The realloc function 
Synopsis 
1 
#include <stdlib.h> 
void *realloc(void *ptr, size_t size); 

Description 
2 The realloc function deallocates the old object pointed to by ptr and returns a 
pointer to a new object that has the size specified by size. The contents of the new 
object shall be the same as that of the old object prior to deallocation, up to the lesser of 
the new and old sizes. Any bytes in the new object beyond the size of the old object have 
indeterminate values. 
3 If ptr is a null pointer, the realloc function behaves like the malloc function for the 
specified size. Otherwise, if ptr does not match a pointer earlier returned by a memory 
management function, or if the space has been deallocated by a call to the free or 
realloc function, the behavior is undefined. If memory for the new object cannot be 
allocated, the old object is not deallocated and its value is unchanged. 
Returns 
4 
The realloc function returns a pointer to the new object (which may have the same 
value as a pointer to the old object), or a null pointer if the new object could not be 
allocated. 

Как вы можете видеть, это не определяет особый случай перераспределить вызовов, где размер равен 0. Вместо этого, он только утверждает, что указатель NULL возвращается при ошибке выделения памяти и указатель во всех других случаях. Тогда указатель, указывающий на 0 байтов, будет жизнеспособным вариантом.

Цитирую a related question:

Более интуитивно, перераспределить это «концептуально эквивалентны» в таНос + тетсру + бесплатно на другой указатель, и таНос-ки 0 байт блок памяти возвращается либо NULL либо уникальный указатель, который нельзя использовать для хранения чего-либо (вы запросили 0 байтов), но все же освобождаетесь. Итак, нет, не используйте realloc, как это, он может работать на некоторых реализациях (а именно Linux), но это, безусловно, не гарантируется.

В другом ответ на что связанные состояниях вопроса, поведение realloc(ptr, 0) явно определяются как реализации определяется в соответствии с действующим стандартом C11:

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

+0

thx Это то, что я хотел, я хочу снова использовать realloc в более позднее время – user3021085

+0

@ user3021085: вы можете освободить как можно больше памяти, сохраняя при этом указатель, используя 'realloc (pointer, 1)' , который высвободит близкую ко всей памяти, и у вас все еще есть указатель на готовый –

+0

да, но у меня есть какая-то информация, которую я проверяю. если я выделяю 1, я могу получить неопределенное поведение – user3021085

1

Я бы использовал realloc, чтобы дать указателю более или менее память, но не пустить его. Чтобы очистить указатель, я буду использовать его бесплатно.

+1

«* to empty *» указатель не является общим выражением (по крайней мере, не в контексте программирования C). Более того, он вводит в заблуждение и не относится к тому, что происходит, когда указывает 'free()' память, на которую ссылается указатель. – alk

4

realloc() Используется для увеличения или уменьшения объема памяти, а не для освобождения памяти.

Check this и использовать free() для освобождения памяти (link).

2

Использовать free(pointer); pointer = 0 вместо realloc(pointer, 0).

2

Я не думаю, что вы имеете в виду «пусто»; это означало бы «установить его на какое-то определенное значение, которое я считаю пустым» (часто все биты нуль). Вы имеете в виду бесплатное или де-распределение.

The manual page говорит:

Если PTR является NULL, то вызов эквивалентен malloc(size), для всех значений size; если size равен нулю, а ptr не равен NULL, то звонок эквивалентен free(ptr).

Традиционно можно использовать realloc(ptr, 0); как синоним free(ptr);, так же, как вы можете использовать realloc(NULL, size); как синоним malloc(size);. Я бы не рекомендовал его, но это немного запутанно, а не то, как люди ожидают его использования.

Однако, в настоящее время в современном C определение поменялось: теперь realloc(ptr, 0); освободит старую память, но это не очень хорошо определено, что будет сделано в следующем: это определяется реализацией.

Итак: не делать этого: использовать free() для снятия выделения памяти, и пусть realloc() использовать только для изменения размера к чему-то ненулевым.

+1

Этот способ использования 'realloc()' кажется устаревшим. Пожалуйста, взгляните на мой ответ. – alk

+0

@alk Да, кажется, он стал менее четко определенным. Я отредактировал, спасибо. – unwind

+0

"теперь realloc (ptr, 0), освободит старую память, но не определено, что будет сделано дальше: она определена в соответствии с реализацией". - Я не уверен, что это правда. Если 'realloc' возвращает' NULL', то это указывает на отказ в распределении, а при сбое распределения старая память не освобождается. – hvd

2
void* realloc (void* ptr, size_t size); 

В C90:

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

В C99:

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

2

Используйте free(), чтобы освободить динамически выделенную память.

Хотя бывшие Документации утверждают, что realloc(p, 0) эквивалентно free(p), то Lastest POSIX documentation Явно утверждает, что это не так:

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

И более:

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

Смежные вопросы