realloc如何知道原始数据的大小?
void *realloc(void *ptr, size_t size);
所以,如果实现是这样的:
temp = malloc(size);
memcpy(.. // How much to copy?
free(ptr);
return temp;
我意识到这不是最初的实现,并且realloc并不总是免费,但是当它发生时,它复制了多少?
编辑: 谢谢你的回答。但是,我如何在我的代码中使用malloc / free /..?
实现realloc答案 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标准库中实现的。