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 会释放其余部分吗? [复制]