我出于某种原因包裹malloc()
。我希望有一些(系统特定的,运行时)信息,而不仅仅是调用它。例如:
malloc()
是什么?realloc()
将使用相同的原始地址成功或需要移动。注意:我希望尽可能提供便携式答案,但特定于平台的答案仍然相关:Linux,Windows,MacOs,Un * x。
答案 0 :(得分:5)
glibc实现malloc_usable_size
,它返回可供应用程序使用的实际分配大小。一些替代malloc
也可以实现它。请注意,即使请求的新大小大于realloc
,glibc也可以执行非移动malloc_usable_size
,因此它不适用于此目的。
对于你要问的其他事情,没有明确的答案。从理论上讲,malloc
应该提供至少与_Alignof (max_align_t)
对齐的内存,但是由于各种原因,许多实现都不会这样做:
max_align_t
来自GCC之类的编译器,因此反映了编译器的世界观,而不是malloc
提供的内容(请参阅glibc malloc is incompatible with GCC 7示例)。 C标准假设统一实现,但实际上,编译器,C运行时库,甚至malloc
都是单独的组件,是从不同的源构建的,并且在不同的发布周期中,因此它们可能会脱离同步,编译时常量(例如_Alignof (max_align_t)
)很少能准确反映malloc
在运行时的作用。malloc
实现可能具有内部约束,这导致更大的对齐,然后是体系结构规范所要求的。应用程序显然不能依赖于它,但它仍然是可观察的。关于非移动realloc
的问题甚至没有正确答案:对于多线程程序,另一个线程可能会放置一个分配,阻止在确定调整大小限制之间扩大当前分配和实际的realloc
电话。 realloc
的非移动版本可能是一个有用的补充,但界面会有很大不同(可能是的某些内容,如果可能的话请调整大小到这个最大值而不移动块,否则返回最大可能的或类似的东西。)
答案 1 :(得分:3)
如果您想要对这些问题进行便携式回答,最好的办法是实施自己的分配方案。不使用名称malloc()
,calloc()
,realloc()
,free()
,strdup()
等会更安全,因为您可能会遇到动态名称问题解决方案,即使您重新实现标准功能符合要求。
您可以通过在每个模块的头部定义一组宏(通过公共头文件)来控制您控制的任何源代码来调用您的分配器。
使用特定于系统的技巧从分配器的元数据中检索信息是有风险的,因为您的程序将动态绑定到C库,因此这些结构可能会从一个系统更改为另一个系统,即使对于同一操作系统也是如此。 p>
在较低级别的系统调用(例如malloc()
或其他系统特定的内容)方面重新实现mmap()
似乎看似简单,但要使其正确,稳定,高效并且需要进行大量工作。可靠。您应该查看malloc
可用的经过验证的替代实现,并尝试根据您的需要定制它们。