realloc是如何在C标准库中实现的?
我找不到realloc是如何在C标准库中实现的?,c,realloc,C,Realloc,我找不到realloc函数的任何源代码,它似乎打破了C的基本规则:它不需要占用内存的长度来重新分配 在不知道原始内存长度的情况下,如何重新分配内存 我如何自己实现这个功能 至少有3个考虑因素使得完全在“userland”C中实现realloc变得困难或不可能 与malloc和free使用的相同数据结构交互 malloc和realloc需要返回适合任何对象的存储。直到C11,我们还没有所有必要的宏来100%可移植地计算这种对齐方式 有一个棘手的语言律师原因是,malloc和realloc不能在po
realloc
函数的任何源代码,它似乎打破了C的基本规则:它不需要占用内存的长度来重新分配
至少有3个考虑因素使得完全在“userland”C中实现
realloc
变得困难或不可能
malloc
和free
使用的相同数据结构交互malloc
和realloc
需要返回适合任何对象的存储。直到C11,我们还没有所有必要的宏来100%可移植地计算这种对齐方式malloc
和realloc
不能在portable C中实现。我可能在这里混淆了术语,但问题是,在函数计算了它将返回的指针值之后,它无法放弃“有效类型”它已与存储关联。因此,即使您可以让您的版本工作,它实际上是非标准的*oldmem
是指向旧内存的指针,在我们的例子中是指针ptr
。而bytes
是要分配的大小,在我们的例子中是80
。此函数有很多检查,如检查指针是否为空,如果是,将其视为简单的malloc
函数,检查字节是否为0,如果是,将其视为自由的,等等。我们对以下几行感兴趣:
/* chunk corresponding to oldmem */
const mchunkptr oldp = mem2chunk (oldmem);
/* its size */
const INTERNAL_SIZE_T oldsize = chunksize (oldp);
这意味着所有信息都保存在内部(在malloc程序头中,正如@SirDarius之前在注释中指出的那样),即每个指针及其关联的大小。如果一切正常,则调用另一个函数(在本例中):
此函数用于分配内存中的实际大小。并返回一个新的指针,该指针最终由\uu libc\u realloc
返回,我们在寄存器rax
中接收该指针
我自己如何实现此功能?
如果您感兴趣,可以查看完整的代码。使用malloc
分配的内存通常有一个包含此信息的头,通常位于内存中malloc返回的指针之前(实现可能不同,但这是一种常见的方法)。此信息是C库的内部信息。这就是允许free
在不使用尺寸参数的情况下工作的原因。如果你想实现realloc
,你可能也想实现malloc
和friends。@JL2210它是真实的、完整的和高效的(在它能够实际调整区块大小,包括mremap
用法方面)在单个文件中实现。realloc
和free
仅在传递的指针用于以前使用相关分配例程分配的内存(或为空指针)时定义。这些例程一起工作,以保存有关它们提供的分配的信息。因此,当传递指向realloc
或free
的指针时,您不需要传递分配的内存长度,因为例程已经具有该信息。对于通过本32位教程完成的工作(请小心,您可以扩展它以处理64位)注意,有许多处理内存块的策略,例如使用“边界标记”。例如,参见K&R.naah中的malloc
realloc
和free
的示例代码,3稍有偏离。。。问题是您不能执行从char[]
返回字节的malloc
,因为它有一个声明的类型,而且C标准不提供任何方法返回未声明类型的字节,除非malloc
&那么,如果您正在编写自己的malloc
,并且不依赖它们,那么这些未类型化的字节从何处获得:D有效类型不会与存储永久关联,您始终可以通过分配覆盖它!如果一个值通过一个类型不是字符类型的左值存储到一个没有声明类型的对象中,那么该左值的类型将成为该访问和后续不修改存储值的访问的有效对象类型
400604: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
400608: be 50 00 00 00 mov esi,0x50
40060d: 48 89 c7 mov rdi,rax
400610: e8 bb fe ff ff call 4004d0 <realloc@plt>
400615: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
void * __libc_realloc (void *oldmem, size_t bytes)
/* chunk corresponding to oldmem */
const mchunkptr oldp = mem2chunk (oldmem);
/* its size */
const INTERNAL_SIZE_T oldsize = chunksize (oldp);
_int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
INTERNAL_SIZE_T nb)