realloc 如何知道要复制多少?

Posted

技术标签:

【中文标题】realloc 如何知道要复制多少?【英文标题】:How does realloc know how much to copy? 【发布时间】:2011-03-29 10:24:53 【问题描述】:

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

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

那么,如果实现是这样的:

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

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

编辑: 感谢您的回答。但是我怎样才能在我的代码中使用 malloc/free/.. 实现 realloc?

【问题讨论】:

您的 realloc 实现必须遵循 malloc 和 free 的实现。在没有 malloc 和 free 所拥有的特殊知识的情况下实现它是不可行的。如果您确实让它与一个 malloc 实现一起使用,它可能无法与其他实现一起使用。 【参考方案1】:

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

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

【讨论】:

取决于实现。您可以放心地假设您无法以任何便携式方式访问它。【参考方案2】:

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

如果您已经在使用 malloc 和 free,为什么不直接使用 realloc? 否则,您可以查看 MSVC/gcc 等附带的 CRT 源代码(或者仅下载它,在 GCC 的情况下),看看它们是如何实现的。 如果您运行的是自定义分配器,那么它的情况会更复杂一些,例如:我使用带有平板类型系统的二进制 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;

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

当您malloc 一些内存时,您获得的块通常是一个固定偏移量到一个更大的数据结构中,该结构还包含额外的信息,特别是块的大小。您可以通过注意malloc 返回的每个地址在以十六进制打印时以8 结尾(例如,将%p 替换为printf)来验证这在某些系统上是否正确。当然realloc可以把这个偏移量倒过来,回到内存管理结构,从而得到大小;从那里开始,能够知道要复制多少(必要时)是微不足道的……

【讨论】:

【参考方案5】:

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

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

【讨论】:

以上是关于realloc 如何知道要复制多少?的主要内容,如果未能解决你的问题,请参考以下文章

realloc 和 memcpy 是如何工作的?

`realloc` 如何在后台实际工作?

realloc 调用会引入多少开销?

我可以假设调用较小大小的 realloc 会释放其余部分吗? [复制]

是真的吗,现代操作系统在调用 realloc 时可能会跳过复制

在C中用realloc()截断字符串?