На самом деле, последний из них эквивалентен звонку на free()
. Внимательно прочитайте спецификацию realloc()
, и вы обнаружите, что она может распределять данные заново или изменять размер выделения (который, особенно если новый размер больше старого, может перемещать данные), и это может освободить память тоже. На самом деле, вам не нужны другие функции; все они могут быть записаны в терминах realloc()
. Не то чтобы кто-то в здравом уме сделал бы это ... но это можно было сделать.
См. « Написание твердого кода » Стива Магуайра для полного анализа опасностей семейства функций malloc()
. См. Веб-сайт ACCU для полного ознакомления с опасностями чтения «Написание твердого кода». Я не уверен, что это так плохо, как об этом говорят обзоры - хотя его полное отсутствие обработки const
действительно датирует его (назад к началу 90-х, когда C89 был еще новым и широко не реализованным ).
D Примечания Макки о MacOS X 10.5 (BSD) интересны ...
Стандарт C99 гласит:
7.20.3.3 Функция malloc
Синопсис
#include <stdlib.h>
void *malloc(size_t size);
Описание
Функция malloc выделяет пространство для объекта, размер которого определяется размером и
чье значение не определено.
Возвращает
Функция malloc возвращает либо нулевой указатель, либо указатель на выделенное пространство.
7.20.3.4 Функция realloc
Синопсис
#include <stdlib.h>
void *realloc(void *ptr, size_t size);
Описание
Функция realloc освобождает старый объект, на который указывает ptr, и возвращает
указатель на новый объект, размер которого указан по размеру. Содержание нового
объект должен быть таким же, как у старого объекта до освобождения, до меньшего из новых и старых размеров. Любые байты в новом объекте, превышающие размер старого объекта, имеют неопределенные значения.
Если ptr является нулевым указателем, функция realloc ведет себя как функция malloc для
указанный размер. В противном случае, если ptr не совпадает с указателем, ранее возвращенным
функции calloc, malloc или realloc, или если пространство было освобождено вызовом
для функции free или realloc поведение не определено. Если память для нового
объект не может быть размещен, старый объект не освобожден и его значение не изменилось.
Возвращает
Функция realloc возвращает указатель на новый объект (который может иметь тот же
значение как указатель на старый объект), или нулевой указатель, если новый объект не может быть
выделяется.
Помимо редакционных изменений из-за дополнительных заголовков и функций, стандарт ISO / IEC 9899: 2011 говорит то же самое, что и C99, но в разделе 7.22.3 вместо 7.20.3.
Страница man для realloc Solaris 10 (SPARC) гласит:
Функция realloc () изменяет размер указателя блока на ptr для размера байтов и возвращает указатель на (возможно, перемещенный) блок. Содержимое будет неизменным вплоть до меньшего из новых и старых размеров. Если новый размер блока требует перемещения блока, пространство для предыдущего создания блока освобождается. Если новый размер больше, содержимое вновь выделенной части блока не определено. Если ptr равно NULL, realloc () ведет себя как malloc () для указанного размера. Если размер равен 0, а ptr не является нулевым указателем, указанное пространство освобождается.
Это довольно явное выражение 'оно работает как free ()'.
Однако, то, что MacOS X 10.5 или BSD говорит что-то другое, подтверждает часть моего первого абзаца «Никто в здравом уме».
Есть, конечно, C99 Обоснование ... Там написано:
7.20.3 Функции управления памятью
Обработка нулевых указателей и запросов на выделение нулевой длины в определении этихотчасти руководствовался желанием поддержать эту парадигму:
OBJ * p; // pointer to a variable list of OBJs
/* initial allocation */
p = (OBJ *) calloc(0, sizeof(OBJ));
/* ... */
/* reallocations until size settles */
while(1) {
p = (OBJ *) realloc((void *)p, c * sizeof(OBJ));
/* change value of c or break out of loop */
}
Этот стиль кодирования, не обязательно одобренный Комитетом, как сообщается, широко распространен
использовать.
Некоторые реализации возвращали ненулевые значения для запросов на выделение нулевых байтов.
Хотя эта стратегия имеет теоретическое преимущество, заключающаяся в различении «ничего» и «нуля» (нераспределенный указатель и указатель на пробел нулевой длины), она имеет более убедительный характер.
Теоретический недостаток необходимости концепции объекта нулевой длины. Так как такие объекты
не может быть объявлено, единственный способ, которым они могли бы появиться, было бы через такие
запросы на выделение.
Комитет С89 решил не принимать идею объектов нулевой длины. Распределение
поэтому функции могут возвращать нулевой указатель для запроса на выделение нулевых байтов. Обратите внимание, что это лечение не исключает изложенную выше парадигму.
тихое изменение в C89
Программа, которая опирается на запросы выделения нулевого размера, возвращающие ненулевой указатель
будет вести себя по-другому.
[...]
7.20.3.4 Функция realloc
Допустим нулевой первый аргумент. Если первый аргумент не равен нулю, а второй аргумент равен 0, то вызов освобождает память, указанную первым аргументом, и нулевой аргумент может быть
вернулся; C99 соответствует политике запрещения объектов нулевого размера.
Новая функция C99: функция realloc была изменена, чтобы было ясно, что
объект освобождается, новый объект выделяется, а содержимое нового объекта совпадает с
это из старого объекта до меньшего из двух размеров. C89 попытался указать, что новый объект был тем же объектом, что и старый объект, но мог иметь другой адрес. Это конфликты
с другими частями стандарта, которые предполагают, что адрес объекта является постоянным во время его
продолжительность жизни. Кроме того, реализации, которые поддерживают фактическое распределение, когда размер равен нулю, не
обязательно верните нулевой указатель для этого случая. C89, по-видимому, требует нулевого возвращаемого значения, и
Комитет счел это слишком ограничительным.
Томас Падрон-МакКарти наблюдается :
C89 прямо говорит: «Если размер равен нулю, а ptr не является нулевым указателем, объект, на который он указывает, освобождается». Значит, они удалили это предложение в C99?
Да, они удалили это предложение, потому что оно включено в первое предложение:
Функция realloc освобождает старый объект, на который указывает ptr
Там нет комнаты для маневра; старый объект освобожден. Если запрошенный размер равен нулю, вы получаете все, что может malloc(0)
вернуть, который часто (обычно) является нулевым указателем, но может быть ненулевым указателем, который также может быть возвращен в free()
, но который не может быть разыменован по закону .