realloc如何知道要复制多少?

时间:2010-08-13 11:43:12

标签: c realloc

realloc如何知道原始数据的大小?

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

所以,如果实现是这样的:

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

我意识到这不是最初的实现,并且realloc并不总是免费,但是当它发生时,它复制了多少?

编辑: 谢谢你的回答。但是,我如何在我的代码中使用malloc / free /..?

实现realloc

5 个答案:

答案 0 :(得分:19)

它知道因为malloc在你调用它时记录了这些信息。毕竟,系统必须始终跟踪已分配块的大小,以便它不会两次分配特定的内存区域。

如果你的意思是“它怎么知道到目前为止我写过多少阵列”,它不需要。它也可以复制任何未初始化的垃圾。

答案 1 :(得分:3)

But how can I then implement realloc in my code with malloc/free/..?

如果您已经在使用malloc&免费,为什么不使用realloc? 否则你可以看看MSVC / gcc等附带的CRT源(或者只是下载它,如果是GCC),看看它们是如何实现的。 如果你运行一个自定义分配器,那么它更具一些情境,例如:我使用带有slab类型系统的二进制bin,在这种情况下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;
}

答案 2 :(得分:1)

realloc(以及malloc和free)可以完全访问构成堆的整个数据结构。在该数据结构中,有关块大小的信息,realloc需要知道,免费也是如此。

答案 3 :(得分:1)

当你malloc一些内存时,你得到的块通常是一个固定的偏移量,它是一个更大的数据结构,它也包含额外的信息,特别是块的大小。您可以通过注意malloc返回的每个地址在以十六进制打印时以8结尾(例如,使用%p替换为{{1}来验证在某些系统上是否属实})。当然,printf可以反转这个偏移量并返回到内存管理结构,从而获得大小;从那里,能够知道复制多少(必要时)是微不足道的......

答案 4 :(得分:1)

为什么不查看你正在使用的C标准库中如何实现malloc / calloc / realloc / free?

或者,如果您无法访问源代码,请查看它是如何在其中一个开源C标准库中实现的。