c - 我应该采取什么预防措施来制作不调用未定义行为的内存池?

标签 c language-lawyer undefined-behavior c11 strict-aliasing

我最初的问题是,在一个项目中,我有几个共享生命周期的对象(即,一旦我释放其中一个,我就会释放它们),然后我想分配一个内存块。我有三种不同对象类型的数组,struct foovoid *char。起初我想 malloc() 像这样的 block :

// +---------------+---------+-----------+---------+---------+
// | struct foo[n] | padding | void *[m] | padding | char[o] |
// +---------------+---------+-----------+---------+---------+

但是……我如何在不调用未定义行为的情况下完成此操作?即,尊重类型别名规则、对齐...如何正确计算内存块大小、声明内存块(及其有效类型),以及如何正确获取指向其中所有三个部分的可移植指针?

(我知道我可以 malloc() 3 个 block ,这将导致三个 free(),但我想知道如何使用一个单独的 block ,同时仍然表现良好。)

我想将我的问题扩展到一个更一般的问题:实现 memory pool 应该采取哪些预防措施?对于具有任意大小和对齐方式的对象,同时保持程序的良好运行? (假设可以在不调用未定义行为的情况下实现它。)

最佳答案

无论您多么努力,都不可能在纯 C 中实现 malloc

你总是在某个时候违反严格的别名。为避免疑义,使用没有动态存储持续时间的 char 缓冲区也将违反严格的别名规则。您还必须确保返回的任何指针都具有适当的对齐方式。

如果您乐于将自己束缚在特定平台上,那么您不妨转向 malloc 的特定实现以获取灵感。

但是为什么不考虑编写一个 stub 函数来调用 malloc 并建立一个包含其他已分配对象的表呢?您甚至可以实现某种观察者/通知框架。另一个起点可能是用 C 语言编写的著名垃圾收集器。

关于c - 我应该采取什么预防措施来制作不调用未定义行为的内存池?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39640620/

相关文章:

c - 动态二维数组未正确创建

c - 是否保证执行 memcpy(0,0,0) 是安全的?

c++ - 哪种未定义的行为允许这种优化?

c - -I/path 和 -L/path 放入代码中

c++ - 适用于调试但不适用于发布

c - Free() 语句崩溃?帮助这个函数解决:(

c++ - constexpr 和 CRTP : compiler disagreement

c++ - 使用指针显式调用指向对象的析构函数后,指针持有什么样的值?

c++ - 使用 const_cast 添加 const 时的未定义行为?

c++ - 未初始化变量的后果 : int vs unsigned char