2016-03-11 4 views
2

В этом фрагменте кода realloc эквивалентен malloc, но я не могу получить логику., когда realloc() эквивалентен malloc() в C?

int *ptr=(int*) realloc(NULL,10*sizeof(int)); 

почему он создает новый блок, так как NULL макрос определен в stdio.h, как 0, так это означает, что он указывает на базовый адрес 0, который в большинстве машин является системная область, так как можно перераспределить начать выделение памяти из базового адреса 0 для 10 целых чисел, почему это не ошибка сегментации?

+0

Передача NULL не означает, что будет использоваться адрес 0. – 2501

+0

Но это макрос, значение которого равно 0, а первый аргумент realloc - это указатель, поэтому, когда мы передаем 0 в переменную-указатель, это означает, что 0 является адресом, не так ли? – user123

+3

Вы делаете много предположений, которые не соответствуют действительности. – 2501

ответ

3

Для уточнения: это означает, что функция realloc проверяет, является ли ее первый аргумент 0 (указатель NULL) и если да, то ведет себя как malloc или просто вызывает malloc.

2

NULL макрос определен в stdio.h, как 0, так это означает, что он указывает на базовый адрес 0

Это не так. NULL - это макрос для нулевого указателя, который необязательно указывает на базовый адрес 0. См. C FAQ.


Чтобы ответить на ваш главный вопрос, realloc ведет себя как malloc, когда первый аргумент является нулевым указателем.

+1

Чтобы быть разборчивым, NULL является макросом для _a_ нулевого указателя _constant_. Указатель, которому присваивается константа нулевого указателя, становится нулевым указателем. Таким образом, ничего не называется «_the_ null pointer». Для получения дополнительной информации, [см. Это] (http://stackoverflow.com/a/32136460/584518). – Lundin

3

так, как можно перераспределить начать выделение памяти из базового адреса 0

От realloc руководства:

В случае PTR является нулевым указателем, то функция ведет себя как таНос, назначая новый блок байтов размера и возвращает указатель на его начало.

Таким образом, в случае предыдущий указатель NULL, это не значит, что realloc должен начать выделение базового адреса 0. В самом деле, он будет вести себя как malloc, выделяя новый блок памяти.

0

Еще один ответ, все прекрасно объяснили, но пропустили какое-то хорошее наблюдение.

Следующее поведение взято из Linux man. Вам может понравиться читать документ для вашей платформы. realloc(void *ptr, size_t size) было иметь плохой дизайн, пытается выполнить многие задачи, например

1) если ptr == NULL, он ведет себя как malloc(size)

2) если ptr != NULL && size == 0, он ведет себя как free(ptr)

Более подробную информацию на man 3 realloc.

Таким образом, предпочтительно иметь обертку для realloc, особенно для использования , как ptr = realloc(ptr, size);, что приводит к утечке.

void* my_realloc(void *oldPtr, size_t newSize) 
{ 
    void *newPtr = NULL; 
    if ((newPtr = realloc(oldPtr, newSize)) == NULL) 
    { 
     free(oldPtr); 
     return NULL; 
    } 
    return newPtr; 
} 
+0

'realloc (some_pointer, 0)' возвращает 'NULL' или указатель не -NULL'. IMO, слабость спецификации 'realloc()'. 'my_realloc()' делает то же самое - никаких улучшений нет. Лучше, если 'realloc (some_pointer, 0)' возвращен не -NULL', поэтому возвращаемое значение 'NULL' _only_ произошло с ошибкой. – chux

+0

# 2 не соответствует действительности. 'realloc (not_null_pointer, 0)' может возвращать действительный (не -NULL') указатель. Это не похоже на 'free()'. – chux

+0

@chux, который был взят из linux 'man 3 realloc' – dlmeetei