Что делать, если 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 4

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().