c语言 - 如何获取有关 malloc() 行为的信息?



出于某种原因,我正在包装malloc()。我希望获得一些(特定于系统的运行时(信息,而不仅仅是通过调用它所能获得的信息。例如:

  • malloc()用于分配的最小对齐方式是多少?
  • 在分配特定的内存段时,它实际分配了多少(理论上这可能超过请求的数量(?
  • (假设没有其他并发操作(realloc()是否会使用相同的原始地址成功或需要移动。

注意:我希望尽可能便携的答案,但特定于平台的答案仍然相关:Linux,Windows,MacOs,Un*x。

glibc 实现了malloc_usable_size,它返回可供应用程序使用的实际分配大小。 一些替代malloc也实现了它。 请注意,glibc 可以执行非移动realloc,即使请求的新大小大于malloc_usable_size,因此它对此没有用。

对于你要问的其他事情,没有明确的答案。 从理论上讲,malloc应该提供至少与_Alignof (max_align_t)对齐的内存,但是由于各种原因,许多实现没有这样做:

  • max_align_t来自像GCC这样的编译器,因此反映了编译器的世界观,而不是malloc提供的内容(参见glibc malloc与GCC 7不兼容的示例(。 C 标准假定实现统一,但实际上,编译器、C 运行时库甚至malloc都是独立的组件,从不同的源构建,并且在不同的发布周期上构建,因此它们可能会不同步,并且像_Alignof (max_align_t)这样的编译时常量很少能准确反映malloc运行时的作用。
  • 在 x86-64 上为 8 或 4 字节的分配提供 ABI 规定的 16 字节对齐是浪费。
  • malloc实现可能具有内部约束,这些约束会导致比体系结构规范所需的更大的对齐。 应用程序显然不能依赖它,但它仍然是可观察的。

您关于非移动realloc的问题甚至没有正确的答案:对于多线程程序,另一个线程可能会放置一个分配,该分配阻止在确定调整大小限制和实际realloc调用之间扩大当前分配。realloc的非移动版本可能是一个有用的补充,但界面会完全不同(可能的话,请在不移动块的情况下调整到这个最大值,否则返回最大可能的大小或类似的东西(。

如果你想要一个可移植的答案来回答这些问题,你最好的办法是实现你自己的分配方案。 不使用名称malloc()calloc()realloc()free()strdup()等会更安全,因为即使您重新实现标准函数是一致的,也可能会遇到动态名称解析的问题。

您控制的任何源代码都可以通过在每个模块的头部定义一组宏(通过公共头文件(来调用分配器。

使用特定于系统的技巧从分配器的元数据中检索信息是有风险的,因为程序将动态绑定到 C 库,因此此类结构可能会从一个系统更改为另一个系统,即使对于同一操作系统也是如此。

根据较低级别的系统调用(如mmap()或其他系统特定的东西(重新实现malloc()似乎看起来很简单,但要使其正确、稳定、高效和可靠需要做很多工作。 您应该查看可用的经过验证的malloc替代实现,并尝试根据您的需求对其进行定制。

最新更新