Что делать, если NULL и размер 0 передаются в realloc()?
Определена ли реализация поведения? Если NULL и size = = 0 передаются в realloc()
:
int main(void)
{
int *ptr = NULL;
ptr = realloc(ptr, 0);
if(ptr == NULL)
{
printf("realloc fails.n");
goto Exit;
}
printf("Happy Scenario.n");
Exit:
printf("Inside goto.n");
return 0;
}
Приведенный выше код должен выводить "realloc fails", верно? Но это не так? Я где-то читал, что этот вызов realloc
может также возвращать NULL. Когда это происходит?
3 ответа:
Это поведение определяется реализацией.
Из стандарта C :
Секция 7.22.3.5 (
realloc
):3 если
ptr
является нулевым указателем, функцияrealloc
ведет себя как функцияmalloc
для указанного размера. в противном случае, еслиptr
не соответствует указателю, ранее возвращенному системой управления памятью функция, или если пространство было освобождено вызовом функцияfree
илиrealloc
, поведение которой не определено. Если память для нового объекта не может быть выделена, старый объект не освобождается, и его значение остается неизменным.Так что
realloc(NULL, 0)
то же самое, чтоmalloc(0)
Если мы тогда посмотрим на раздел 7.22.3.4 (
malloc
):2 функция
malloc
выделяет пространство для объекта, размер которого задан функциейsize
и значение которого не определено.3 функция
malloc
возвращает либо нулевой указатель, либо указатель на выделенное пространство.Стандарт не указывает, что происходит, когда
0
передается.Но если вы посмотрите на Linux man page :
Функция
malloc()
выделяет байты размера и возвращает указатель на выделенная память. Память не инициализируется. Если размер равен 0, затемmalloc()
возвращает либо NULL, либо уникальное значение указателя, которое может позже будет успешно передан вfree()
.Он явно утверждает, что возвращаемое значение может быть освобождено, но не обязательно равно NULL.
Напротив, MSDN говорит:
Если размер равен 0, Мэллок выделяет элемент нулевой длины в куче и возвращает допустимый указатель на этот элемент. Всегда проверяйте возврат от Мэллок, даже если объем запрашиваемой памяти невелик.
Таким образом, для MSVC вы не получите нулевой указатель.
Realloc (3) doc:
Если ptr равен NULL, то вызов эквивалентен malloc (size), для всех значений size
Malloc (3) doc:
Если size равен 0, то malloc () возвращает либо NULL, либо уникальное значение указателя, которое впоследствии может быть успешно передано free ().
Так что да, это реализация определена, вы получите либо null, либо указатель, который вы можете освободить.
Вызов
realloc(NULL, size);
Эквивалентно
malloc(size);
И что делает
malloc()
, когда его просят выделить 0 байт, немного неясно, стандарт не говорит. Я думаю, что это определяется реализацией. Это в принципе "не имеет значения"; либо он возвращаетNULL
, либо он возвращает указатель, где вы можете легально получить доступ к нулевым байтам, они очень похожи. Оба могут быть переданы вfree()
.