Как realloc знает, сколько копировать?
как realloc знает размер исходных данных?
void *realloc(void *ptr, size_t size);
Итак, если реализация такова:
temp = malloc(size);
memcpy(.. // How much to copy?
free(ptr);
return temp;
Я понимаю, что это не оригинальная реализация, а realloc не всегда делает бесплатно, но когда это происходит, сколько она копирует?
Изменить:
Спасибо за ответы. Но как я могу реализовать realloc в моем коде с помощью malloc/free/..?
Ответы
Ответ 1
Он знает, потому что malloc
записал эту информацию, когда вы ее назвали. В конце концов, система должна отслеживать размеры выделенных блоков в любом случае, чтобы она не выделяла конкретный регион памяти дважды.
Если вы имеете в виду "как он знает, сколько из массива я написал до сих пор", это не нужно. Он может просто скопировать любой неинициализированный мусор.
Ответ 2
But how can I then implement realloc in my code with malloc/free/..?
Если вы уже используете malloc и бесплатно, почему бы просто не использовать realloc?
иначе вы можете просто взглянуть на источник CRT, который поставляется с MSVC/gcc и т.д. (или просто загрузить его, в случае GCC), и посмотреть, как они его реализуют.
Если вы выполняете собственный распределитель, то это немного более ситуативно, например: я использую двоичный бит с системой типа slab, и в этом случае realloc прост:
void* Reallocate(Manager* pManager, void* pBlock, size_t nSize, const char* szFile, const DWORD dwLine)
{
#if ( MMANAGER_NULL_TO_DEFAULT )
if(pManager == NULL)
pManager = MMANAGER_DEFUALT_MANAGER;
#endif
if(pBlock == NULL)
return Allocate(pManager,nSize,szFile,dwLine);
else if(nSize == 0)
{
Free(pManager,pBlock,szFile,dwLine);
return NULL;
}
BlockHeader* pHeader = GetHeader(pBlock);
size_t nPrevSize = pHeader->pPoolBlock->nSize;
if(nPrevSize < nSize)
{
void* pNewBlock = Allocate(pManager,nSize,szFile,dwLine);
memcpy(pNewBlock,pBlock,nPrevSize);
PoolBlock* pPoolBlock = pHeader->pPoolBlock;
if(pPoolBlock == NULL)
free(pHeader);
else
FreeBlock(pPoolBlock,pHeader);
return pNewBlock;
}
return pBlock;
}
Ответ 3
realloc (и malloc и free) имеют полный доступ ко всей структуре данных, составляющей кучу. В этой структуре данных есть информация о размерах блоков, которые необходимо знать realloc, и, следовательно, и бесплатно.
Ответ 4
Когда вы malloc
некоторая память, ваш блок обычно является фиксированным смещением в большую структуру данных, которая также содержит дополнительную информацию, в частности размер блока. Вы можете убедиться, что это верно для некоторых систем, просто отметив, что каждый адрес, возвращаемый malloc
, заканчивается на 8
при печати в шестнадцатеричном формате (например, с заменой %p
на printf
). Конечно, realloc
может отменить это смещение и вернуться к структуре управления памятью и получить размер; оттуда, возможность узнать, сколько копировать (когда это необходимо) тривиально...
Ответ 5
Почему бы вам просто не посмотреть, как malloc/calloc/realloc/free реализуется в стандартной библиотеке C, которую вы используете?
Или, если у вас нет доступа к исходному коду, посмотрите, как он реализован в одной из стандартных библиотек C с открытым исходным кодом.