【问题标题】:C++ data alignment of unique_ptr<> using _aligned_malloc()使用 _aligned_malloc() 对 unique_ptr<> 进行 C++ 数据对齐
【发布时间】:2016-06-11 22:07:22
【问题描述】:

我试图确保在将对象添加到vector 数据结构之前对齐。响应warning C4316: 'Basic' : object allocated on the heap may not be aligned 16 警告,我有以下Basic 对象:

class Basic
{
public:
    Basic();
    ~Basic();
};

这是一个标准的对象。接下来,分配unique_ptrBasicnew 实例,以便这样做。 (相对于标准指针)

unique_ptr<Basic> e_Basic{new Basic()};

我尝试对齐数据,以便以后避免对齐问题:

e_Basic.reset =_aligned_malloc((size_t)sizeof(Basic), (size_t)(16 + (sizeof(Basic) % 16))); //Verify alignment.

最后添加指向vector数组的指针。

LocalBasicQueue.push_back(move(e_Basic));

编译器说它是犹太洁食,但我的“什么软糖?”代码感正在消失。这会导致指向(肯定)对齐代码的指针吗?

是否可以以这种方式声明(e_Basic.reset) 等于一个指针 [由_aligned_malloc() 返回] 并调用它的unique_ptr&lt;&gt;,并分配新的指针?

【问题讨论】:

  • e_Basic.reset = ...?除非您询问编译器错误,否则请尝试显示正确的代码,最好是 Minimal, Complete, and Verifiable Example
  • 哦,sizeof ... 的结果不用强制转换,它的类型自动为size_t。您还应该尽量避免在 C++ 中进行 C 风格的强制转换,如果可能的话,尽量避免使用一般的强制转换。 如果你需要做演员,先试试static_cast
  • 我编辑了帖子,谢谢。
  • @RashidEllis e_Basic.reset = x; 不是你能做的。你的意思是e_Basic.reset(x);
  • 阅读更多关于 placement new 的信息,如答案中所建议的那样。 IE。只需分配正确的内存量并将其分配给void* 变量。然后使用该指针进行放置 new:e_Basic.reset(new (the_pointer) Basic); 这将使用您通过 _aligned_malloc 分配的内存用于对象和 construct 对象(这是您缺少的构造步骤)。跨度>

标签: c++ vector malloc unique-ptr memory-alignment


【解决方案1】:

该代码存在一些问题。

  1. 您无缘无故地分配、构造并立即销毁 Basic 对象。
  2. 您永远不会在_aligned_malloc 分配的内存中初始化Basic 对象。
  3. 默认情况下unique_ptr 将释放它使用delete 管理的内存,但你没有new 那个内存,你_aligned_malloced 它。这是个坏主意,可能会导致堆损坏和/或崩溃。

您可以通过不使用new Basic() 初始化您的unique_ptr 来解决第一个问题。

第二个可以使用placement new 表达式来修复。

第三个可以通过给unique_ptr 一个自定义删除器来修复,它调用~Basic_aligned_free 而不是delete 请注意虽然unique_ptr&lt;Basic, my_deleter&gt;unique_ptr&lt;Basic&gt; 的类型不同,所以你可以不要把它放入vector&lt;unique_ptr&lt;Basic&gt;&gt;

第二个和第三个问题也可以通过重载Basic::operator newBasic::operator delete分别使用_aligned_malloc_aligned_delete来解决,但这意味着new Basic()总是使用_aligned_malloc,你可以或可能不想要。

【讨论】:

  • 现在还为时尚早,我可以在不进行重大实施更改的情况下进行更改。我是否应该忽略对齐警告并以某种方式相信unique_ptr&lt;Basic&gt; 指向向量中的对齐数据?
  • 不——你应该接受给出的建议。
  • 谢谢,为了澄清,我想确保存储在unique_ptr&lt;Basic&gt; 中的指针是对齐的。
  • 如果您使用_aligned_malloc 分配,您必须使用_aligned_free 释放。它与对齐无关,new 根本不知道内存,因为它没有为您分配它。如果您使用常规的malloc,情况也是如此。
  • 如果您希望所有Basic 对象都使用_aligned_malloc,我还添加了一些关于重载operator newoperator delete 的内容。
猜你喜欢
  • 1970-01-01
  • 2018-10-12
  • 2019-02-08
  • 2013-10-22
  • 1970-01-01
  • 2017-12-05
  • 2018-01-10
  • 2017-02-06
  • 2016-06-20
相关资源
最近更新 更多