Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
realloc是如何在C标准库中实现的?_C_Realloc - Fatal编程技术网

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中实现。我可能在这里混淆了术语,但问题是,在函数计算了它将返回的指针值之后,它无法放弃“有效类型”它已与存储关联。因此,即使您可以让您的版本工作,它实际上是非标准的

  • 考虑一个例子(在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)