类的C ++对齐-对未对齐地址的成员调用

时间:2018-11-26 16:12:45

标签: c++ alignment

我正在使用UBSAN,并遇到以下错误。请注意,我正在使用带有-fsanitize = undefined的clang 6.0.1进行编译。我已经阅读了许多关于SO的背景问题,但仍然无法解决我的特定问题。以下是可供参考的背景问题:

以下是有关C类的一些注意事项:

  • 使用newC* o = new C();)创建类型C的对象
  • 类型C的成员类型A具有64字节对齐。我使用alignof验证了这一点。
  • 使用class alignas(64) C声明C-但这不能解决我的问题

我目前的假设是我需要使用C ++ 17 std::aligned_alloc的C ++ 11等效物来使用对齐的存储来创建对象。但是,我不确定如何最好地做到这一点,或者它是否真的可以解决我的问题。如果可能的话,我宁愿只在类C的定义中解决问题,而不是每次创建C时都解决。建议使用什么方法解决此问题以消除UBSAN错误?

1 个答案:

答案 0 :(得分:1)

如果您的类已具有需要64字节对齐的成员,则该类也将出于必要而已具有64字节对齐。因此,添加显式alignas(64)并不会真正改变任何内容。

这里的基本问题是分配函数(在C ++ 11中)are only required返回与fundamental alignment对齐的内存。 C ++ 11保留了实现定义的定义,无论新[expr.new]/1是否支持过度对齐的类型。 C ++ 17 introduced新扩展的对齐方式和其他分配函数可以解决这个问题(但是,是否以及哪些新扩展的对齐方式仍受实现定义)。

如果您可以切换到支持C ++ 17的编译器,则您的代码可能会正常工作。否则,您可能必须使用一些特定于实现的函数来分配对齐的内存,或者只是滚动您自己的解决方案,例如,基于std::align和新的位置(这也可以在C ++ 11中使用)…