Как перевыделение знает, сколько скопировать?

как перевыделение знает размер исходных данных?

 void *realloc(void *ptr, size_t size);

Так, если реализация похожа на это:

 temp = malloc(size);
 memcpy(.. // How much to copy?
 free(ptr);
 return temp;

Я понимаю, что это не исходная реализация, и перевыделение не всегда делает свободный, но когда это делает, сколько это копирует?

Править: Спасибо за ответы. Но как я могу затем реализовать перевыделение в своем коде с malloc/free/..?

12
задан yper 13 August 2010 в 12:13
поделиться

5 ответов

Он знает, потому что malloc записывал эту информацию, когда вы ее вызывали. В конце концов, система в любом случае должна отслеживать размеры выделенных блоков, чтобы не выделять конкретную область памяти дважды.

Если вы имеете в виду, «как он узнает, какой объем массива я написал на данный момент», это не обязательно. Он также может просто копировать любой неинициализированный мусор.

19
ответ дан 2 December 2019 в 06:07
поделиться

realloc (и malloc, и free) имеют полный доступ ко всей структуре данных, составляющей кучу. В этой структуре данных есть информация о размерах блоков, которую необходимо знать realloc, как и free.

1
ответ дан 2 December 2019 в 06:07
поделиться

Когда вы malloc некоторую память, блок, который вы получаете, обычно представляет собой фиксированное смещение в большую структуру данных, которая также содержит дополнительную информацию, особенно размер блока. Вы можете проверить, что это так в некоторых системах, просто отметив, что каждый адрес, возвращаемый malloc , оканчивается на 8 при печати в шестнадцатеричном формате (например, с % p ] заменой на printf ). Конечно, realloc может изменить это смещение и вернуться к структуре управления памятью, и таким образом получить размер; оттуда легко узнать, сколько копировать (при необходимости)…

1
ответ дан 2 December 2019 в 06:07
поделиться

Но как мне потом реализовать realloc в моем коде с malloc/free/...?

Если вы уже используете malloc и free, почему бы просто не использовать realloc? В противном случае вы можете просто взглянуть на исходники CRT, которые поставляются с MSVC/gcc и т.д. (или просто скачать его, в случае GCC), и посмотреть, как они это реализуют. Если вы используете собственный аллокатор, то это более ситуативно, например: Я использую бинарный бин с системой типов slab, в этом случае перераспределение простое:

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
ответ дан 2 December 2019 в 06:07
поделиться

Почему бы вам просто не посмотреть, как malloc / calloc / realloc / free реализован в стандартной библиотеке C, которую вы используете?

Или, если у вас нет доступа к исходному коду, посмотрите, как это реализовано в одной из стандартных библиотек C.

1
ответ дан 2 December 2019 в 06:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: