Как 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 с открытым исходным кодом.