放置 - 新地址对齐

时间:2017-03-01 01:22:34

标签: c++ memory-management undefined-behavior memory-alignment

根据https://isocpp.org/wiki/faq/dtors#placement-new 传递给placement-new的地址必须正确对齐。但它给出的例子似乎与此相矛盾。

char[]

此缓冲区很可能与Fred对齐,因为它是一个愚蠢的memory,所以T可以指向几乎任何地方。然后它会在此地址上执行新的位置。

示例是否与 DANGER 脚注中的对齐要求相矛盾?

这导致了一个相关的问题:

如何为类型char[]创建对齐的缓冲区(堆栈或堆)(在一个或多个T对象的placement-new中使用)?

缓冲区我指的是某个大小的void*T[]缓冲区,而不是var maxobj = objects.OrderByDescending(i => i.Size).FirstOrDefault(); ,因为这将是对象分配,这会破坏之后进行放置的点。

谢谢。

3 个答案:

答案 0 :(得分:16)

使用if (fileName.IsNull)关键字:

alignas

如果您更喜欢这种结构的库包装,请使用alignas(Fred) char buf[sizeof(Fred)]; ::new (static_cast<void*>(buf)) Fred;

答案 1 :(得分:8)

关于你的第一个问题:根据answers to this related question是的,这个例子弄错了:

  

静态分配的数组与sizeof(element_type)字节对齐    - 对于char,它是1个字节,基本上保证不对齐。

因此数组char memory[sizeof(Fred)]没有Fred的对齐保证。

正确的做法如下(C ++ 11):

alignas(Fred) char memory[sizeof(Fred)];

答案 2 :(得分:3)

对于堆分配,只需使用std::malloc,它可以保证为任何类型分配内存。

对于堆栈分配,如果您有权访问C ++ 11,则可以使用{/ 3}},如

alignas(T) uint8_t data[sizeof(T)];

如果您无法访问C ++ 11,那么您必须回退到特定的编译器属性,如GCC&#39; alignas