您的位置:首页 > 汽车 > 时评 > [Linux/Windows] realloc工作步骤 它怎么知道原来内存大小的?

[Linux/Windows] realloc工作步骤 它怎么知道原来内存大小的?

2025/1/10 11:43:11 来源:https://blog.csdn.net/H_O_W_E/article/details/141953096  浏览:    关键词:[Linux/Windows] realloc工作步骤 它怎么知道原来内存大小的?

函数原型:

void *realloc(void *mem_address, unsigned int newsize); 

1,realloc怎么知道原来内存大小的?

realloc 函数在执行时可能会重新分配一块新的内存,并且在需要时将旧内存中的数据复制到新的内存区域。然而,realloc 并不会直接接收到原始内存块的大小,因为它只接受两个参数:一个是原来的内存地址,另一个是新的内存大小。那么,它是如何知道原内存块的大小以便进行复制的呢?

这依赖于系统的内存管理。

其实,在内存管理的实现中,分配的内存块大小通常是记录在内存分配器的内部数据结构中。通常的做法是,在分配给用户的内存块之前或之后,内存分配器会额外分配一小块空间,用来存储该块内存的元数据,其中包括了内存块的大小。

例如,当你使用 malloc 分配了一块内存时,内存分配器会在返回给你的内存地址之前预留一小部分空间(通常是几个字节),用来存储这块内存的大小和其他元数据。因此,尽管用户代码无法直接访问这些元数据,内存管理器可以通过这些元数据知道每个分配的内存块的大小。

realloc 被调用时,内存分配器可以通过内部管理的数据结构(可能就在给定的 mem_address 前面的一段区域)查找出原来分配的内存块的大小,然后根据情况决定是否需要分配新的内存块并复制数据。

内存分配器的典型工作流程:

  1. malloc 分配内存:内存分配器会在返回给用户的内存地址之前,预留一些字节用于存储该块内存的大小和其他信息。
  2. realloc 查找内存块大小:当调用 realloc 时,分配器通过查找该内存块前面的元数据,得知该内存块的大小。
  3. 重新分配和复制数据:如果新大小比旧大小大且当前块无法扩展,realloc 会分配一个新的足够大的内存块,并将旧块中的数据复制到新的内存块中。

-------------------------------------------------------------------------------------------------------------

2,realloc的内部工作步骤:

  • 1),检查输入指针
    • 如果传递的指针 mem_addressNULLrealloc 的行为和 malloc 类似,它会分配一块新的内存。
    • 如果 newsize 为 0,realloc 通常相当于 free,即释放传入的内存块,并返回 NULL
  • 2),查找当前内存块大小
    • 如果 mem_address 是有效的指针,realloc 会通过内存分配器的元数据找到当前分配的内存块的大小。通常,这些元数据会存储在内存块的前面,或者通过某种全局或局部的表来记录所有分配的内存块。
  • 3),判断是否需要重新分配
    • 如果 newsize 小于或等于当前内存块的大小,通常不需要分配新的内存,直接返回原来的指针即可(可能需要调整内存分配器的元数据,更新分配的大小)。
    • 如果 newsize 大于当前内存块的大小,内存分配器会尝试在原来的位置扩展内存块。如果原来的内存块后有足够的空闲空间,那么可以在原地扩展并返回相同的指针。
  • 4),分配新内存块
    • 如果无法在原地扩展内存块(例如,后面的内存被其他数据占用),realloc 会调用 malloc 分配一块新的、大小为 newsize 的内存块。
  • 5),复制旧数据到新内存块
    • 如果 realloc 分配了新的内存块,接下来会将旧内存块中的数据复制到新内存块中。复制的大小是 min(原内存块大小, newsize),即只复制需要的部分,以免读写越界。
  • 6),释放旧内存块
    • 在数据复制完成后,realloc 会调用 free 释放旧的内存块(如果新的内存块位于不同的位置)。
  • 7)返回新内存块的地址
    • realloc 最后会返回新分配的内存块的地址。如果分配失败,则返回 NULL,并且原内存块不变。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com