一尘不染

重新分配是否保持posix_memalign的内存对齐?

linux

对齐malloc是的posix_memalign,没关系,但是对齐的realloc呢?是否realloc保留对齐方式或如何确保重新分配的内存具有相同的对齐方式?假设Linux和x86_64。


阅读 731

收藏
2020-06-03

共1个答案

一尘不染

不,ISO或POSIX不能保证realloc返回的内存posix_memalign保持相同的对齐方式。A realloc 可以
简单地将当前块扩展到相同的地址,但也可以将其移动到对齐方式比原始地址严格的其他地址。

如果您想要相同的对齐方式,则最好分配另一个块并复制数据。

不幸的是,posix_memalign_realloc在单一UNIX规范中也没有任何功能。

如果您不想 每次都 经历复制数据的麻烦,可以尝试使用realloc (a),如果对齐方式与预期不符, 则只能
调用posix_memalign以获取正确对齐的地址并复制数据到那里,完成后释放旧地址。

这可能导致:

  • 零份(如果当前块可以就地扩展);
  • 一份(如果有realloc副本但碰巧会给您正确对齐的块);要么
  • 两份副本(如果是realloc副本,则由于对齐问题您还必须复制)。

根据底层内存管理的实现,它 可能 还会导致复制数量少于指示的数量。例如,“复制”可能只涉及重新映射存储块,而不是物理移动数据。

因此,您可能需要保留一些统计信息,以查看该方案是否值得。


(a)请记住,POSIX和Linux手册页都没有指定您是否甚至 可以 将这些指针传递给realloc,而只能将它们传递给free

但是,根据当前的GNU libc源代码,它似乎可以工作,尽管不能保证将来会继续工作:-)

我担心它会正常分配内存(标准对齐方式)并传回偏移地址(即,不是分配的实际地址,而是N超出的一个字节),free该地址足够聪明,可以在编织魔术之前将其转换为实际地址。

一种方法是在返回地址之前立即存储 实际 地址,尽管即使对于常规分配,这当然也会导致浪费。

在这种情况下,free可能已经变得智能化了(因为规范说它必须能够处理by所做的分配posix_memalign),但是realloc可能没有被赋予相同的智能性(因为文档对此没有任何说明)。

但是,基于GNU glibc
2.14.1,它实际上分配了比所需更多的内存,然后摆弄了舞台,以释放前空间和后空间,因此返回的地址是“真实”地址,可用于freerealloc

但是,如上所述,文档并不能保证这一点。

2020-06-03