【问题标题】:C++ Aligned Array or vector of "unsigned long" on 64-byte boundary, and associated delete[]64 字节边界上的“unsigned long”的 C++ 对齐数组或向量,以及相关的 delete[]
【发布时间】:2021-09-15 04:37:36
【问题描述】:

我试过了

unsigned long* ulongsArray = new(std::align_val_t{ 64 }) unsigned long[1024];
delete[] ulongsArray;
// ::operator delete[](ulongsArray, std::align_val_t{ 64 });   // same compiler error
// ::operator delete[](new(std::align_val_t{ 64 }) unsigned long[1024], std::align_val_t{ 64 });   // same compiler error

但是,在 VisualStudio 2019 下,出现错误“错误 C2956:通常的释放函数 'void operator delete[](void *,std::align_val_t) noexcept' 将被选为放置释放函数。”这似乎指向 C++17 标准缺乏对对齐数组的 delete[] 的定义。

VisualStudio2019 似乎默认对齐 64 字节边界,以及英特尔编译器。但是,g++ 似乎与 16 字节边界对齐,我需要 64 字节对齐(缓存行)。

【问题讨论】:

  • 最近我们一直在与 C++ 过度对齐的内存发生争执!我们为 Mac(ARM 和 Intel)和 Windows 构建。我认为最终我们必须对不同的平台有不同的调用。这可能有用吗? github.com/NickStrupat/AlignedMalloc
  • 我无法使用 gcc trunk 和 clang trunk 在 Godbolt 上重现此内容。例如。 godbolt.org/z/ebdhrPde6 。但是,我在使用最新的 MSVC 时确实收到了该错误。那么可能特定于编译器实现?
  • JCx - 您的aligned_malloc 和free 实现是否与C++ new 和delete[] 共存?我的很多代码都在使用 new 和 delete[]。
  • C2P1 - 我尝试了第一个替代 delete[] 实现(使用您提供的链接),它也在 gcc 下编译而没有错误。这似乎更适合对齐的新版本。想知道其中一个是否正确使用,是否会导致内存泄漏。

标签: c++ arrays vector memory-alignment


【解决方案1】:

这似乎是 MSVC 编译器的问题,因为它可以使用 gcc 和 clang 正常编译。过去被举报过here

但是,您可以通过执行以下操作来实现您正在寻找的预期结果(跨 MSVC、clang 和 GCC):

unsigned long *ulongsArray = static_cast<unsigned long*>(
        operator new[](sizeof(unsigned long) * 64, (std::align_val_t)(64)));
delete[] ulongsArray;

【讨论】:

  • 以上编译正常,但抛出了 delete[]。第一个替代变体似乎适用于 delete[],并将数组对齐为 64 字节。谢谢!这有很大帮助。我将测试此方法是否存在内存泄漏并进行报告。
  • 在 MSVC 中抛出异常(使用问题中使用的 delete[] 时)。 g++ 似乎可以使用任何一种方法运行:问题中使用的 delete[] 或第一个替代方法(已注释掉)。
  • @DragonSpit 试试alignas(64) 怎么样?根据您要查找的内容,您可以拥有:alignas(64) unsigned long ulongsArray[64];
  • 遗憾的是,我需要在堆上分配一个动态值。 alignas 可以很好地用于在堆栈上分配固定数量,并且比使用 __declspec() 方法要好得多。
猜你喜欢
  • 1970-01-01
  • 2013-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-23
  • 1970-01-01
  • 1970-01-01
  • 2016-12-19
相关资源
最近更新 更多