Как `realloc` работает в фоновом режиме?
Как realloc
работает в фоновом режиме?
Если в старом месте недостаточно памяти
это выделяет два/много блоков памяти и один указатель
указывая на это, а другие связаны с каждым из них
другой или старый регион, скопированный на новое место, где достаточно
доступна память и указатель обновляется до нового адреса и удаляет старую память?
И есть ли realloc
зависимый или независимый от компилятора/ОС?
Ответы
Ответ 1
realloc
пытается расширить доступный диапазон памяти, если в куче имеется достаточное количество памяти. Если нет, то это эквивалентно malloc
блоку нового размера, memcpy
ваше содержимое там, free
старый блок. Это не зависит от ОС и компилятора и зависит от реализации libc
, с которой вы ссылаетесь.
Аналогичным образом: mremap/MREMAP_MAYMOVE
(доступно на современной Linux) попытается расширить ваше виртуальное сопоставление запрошенным размером. Если это невозможно, оно переместит ваше сопоставление на новый виртуальный адрес с достаточным пространством VM за ним, а затем расширит ваше сопоставление. Это очень быстро, если вы часто изменяете размер больших отображений, поскольку физическое копирование не выполняется.
Ответ 2
Реализация realloc()
может выглядеть примерно так:
void * realloc(void *ptr, size_t size)
{
// realloc() on a NULL pointer is the same as malloc().
if (ptr == NULL)
return malloc(size);
size_t oldsize = malloc_getsize(ptr);
// Are we shrinking an allocation? That easy.
if (size < oldsize) {
malloc_setsize(ptr, size);
return ptr;
}
// Can we grow this allocation in place?
if (malloc_can_grow(ptr, size)) {
malloc_setsize(ptr, size);
return ptr;
}
// Create a new allocation, move the data there, and free the old one.
void *newptr = malloc(size);
if (newptr == NULL)
return NULL;
memcpy(newptr, ptr, oldsize);
free(ptr);
return newptr;
}
Обратите внимание, что я вызываю несколько функций с именами, начинающимися с malloc_
здесь. Эти функции фактически не существуют (насколько мне известно) в любой реализации; они предназначены как заполнители, однако распределитель фактически выполняет эти задачи внутри страны.
Поскольку реализация realloc()
зависит от этих внутренних инструментов, ее реализация зависит от ОС. Однако интерфейс realloc()
универсален.
Ответ 3
Если старый указатель не может быть изменен на месте, где будет выделен новый, содержимое будет скопировано, а старый будет освобожден.