Учитывая следующий код:
int *a = NULL;
a = calloc(1, sizeof(*a));
printf("%d\n", a);
a = realloc(a, 0);
printf("%d\n", a);
return (0);
Это возвращается:
4078904
0
Действительно ли это перевыделение эквивалентно свободному?
Примечание: Я использую MinGW под WindowsXP.
Не обязательно.
Часто так и со ссылкой , опубликованной munissor , но на странице руководства Mac OS 10.5 говорится:
Если размер равен нулю и ptr не равен NULL, выделяется новый объект минимального размера. и исходный объект освобождается.
Что такое «объект минимального размера»? Что ж, любой распределитель хранит некоторую информацию о распределении, и для этого требуется пространство, которое часто выделяется в дополнение к пространству, зарезервированному для пользователя. Предположительно «объект минимального размера» - это всего лишь один из этих заголовков плюс ноль байтов пространства, зарезервированного для пользователя.
Я предполагаю, что это положение присутствует для поддержки реализаций, существовавших во время стандартизации, и что эти реализации полезны для отладки поведения распределения.
В ответ на комментарии Джонатана
Рассмотрите разницу между
for (int i=0; i<VERY_BIG_NUMBER; ++i){
char *p = malloc(sizeof(char[10]));
free(p);
}
и
for (int i=0; i<VERY_BIG_NUMBER; ++i){
char *p = malloc(sizeof(char[10]));
realloc(p,0);
}
. При разумной реализации malloc
и free
первый клип делает ] not потребляют память без ограничений. Но если реализация realloc
возвращает эти «объекты минимального размера», она могла бы.
Конечно, этот пример надуманный и основан на понимании того, что подразумевается под «объектом минимального размера», но я думаю, что текст позволяет это.
Короче говоря, если вы имеете в виду бесплатно
, вы должны сказать бесплатно
.
В стандарте C99 §7.20.3.4 (realloc) сказано:
Функция realloc удаляет старый объект, на который указывает ptr, и возвращает указатель на новый объект, имеющий размер, заданный size. Содержимое нового объекта должно быть таким же, как и у старого объекта до деаллокации, вплоть до меньшего из двух значений нового и старого размеров. Любые байты в новом объекте за пределами размера старого объекта имеют неопределенные значения.
Если ptr является нулевым указателем, функция realloc ведет себя как функция malloc для указанного размера. указанного размера. В противном случае, если ptr не совпадает с указателем, ранее возвращенным функциями calloc, malloc или realloc, или если пространство было деаллоцировано вызовом функции функции free или realloc, поведение не определено. Если память для нового объект не может быть выделена, старый объект не деаллоцируется, и его значение остается неизменным.
Это ясно говорит о том, что старый объект деаллоцируется (освобождается). Возвращаемое значение может быть нулевым указателем, или это может быть значение, как указано в общих примечаниях к §7.20.3:
Если размер запрашиваемого пространства равен нулю, поведение определяется реализацией: либо возвращается нулевой указатель, либо поведение такое, как если бы размер был некоторым за исключением того, что возвращенный указатель не должен использоваться для доступа к объекту.
В любом случае, вы не можете разыменовать возвращаемое значение: оно может быть использовано как аргумент в free()
, или передано другим функциям, если они в свою очередь не ссылаются на него.
Это может быть или не быть эквивалентно вызову free
для указателя; результат определяется реализацией.
Из стандарта C99 (§7.20.3/1):
Если размер запрашиваемого пространства равен нулю, поведение определяется реализацией: либо возвращается нулевой указатель, либо поведение такое, как если бы размер был некоторым ненулевым значением, за исключением того, что возвращенный указатель не должен использоваться для доступа к объекту.
Это относится ко всем функциям управления памятью, включая realloc
.