Что произойдет, если я перераспределю, и новый размер будет 0. Это эквивалентно свободному? - PullRequest
8 голосов
/ 30 марта 2010

С учетом следующего кода:

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.

Ответы [ 4 ]

8 голосов
/ 30 марта 2010

Может быть или не быть эквивалентно вызову free по указателю; результат определяется реализацией.

Из стандарта C99 (§7.20.3 / 1):

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

Это относится ко всем функциям управления памятью, включая realloc.

4 голосов
/ 30 марта 2010

Не обязательно.

Часто это происходит так же, как со ссылкой , которую 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 первый клип не потребляет память без ограничений. Но если реализация realloc возвращает эти «объекты минимального размера», это может произойти.

Конечно, этот пример придуман и основан на понимании того, что подразумевается под «объектом минимального размера», но я думаю, что текст это позволяет.

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

2 голосов
/ 30 марта 2010
1 голос
/ 30 марта 2010

Да

Стандарт C99 §7.20.3.4 (realloc) гласит:

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

Если ptr является нулевым указателем, функция realloc ведет себя как функция malloc для указанный размер. В противном случае, если ptr не совпадает с указателем, ранее возвращенным функции calloc, malloc или realloc, или если пространство было освобождено вызовом для функции free или realloc поведение не определено. Если память для нового объект не может быть размещен, старый объект не освобожден и его значение не изменилось.

Это ясно говорит о том, что старый объект освобожден (освобожден). Возвращаемое значение может быть нулевым указателем или значением, указанным в общих примечаниях для §7.20.3:

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

В любом случае вы не можете разыменовать возвращаемое значение: оно может использоваться в качестве аргумента для free() или передаваться другим функциям, если они в свою очередь не ссылаются на него.

...