如何在 C++17 中调用重载对齐的 new 和 delete 运算符?

How to call the overloaded aligned new and delete operators in `C++17`?

cppreference 我们可以看到 newdelete 以及 new[]delete[] 的几个新重载已添加。我找不到任何使用新对齐重载的示例,无论是在 cppreference 上还是在其他任何地方。我已经对它们进行了很长一段时间的试验,但我无法找到如何触发这些对齐的动态分配的调用。任何人有任何想法,请分享一个例子。

它在 cppreference 上,只是隐藏了几个链接: https://en.cppreference.com/w/cpp/language/new

new(2,f) T; // calls operator new(sizeof(T), 2, f)
        // (C++17) or operator new(sizeof(T), std::align_val_t(alignof(T)), 2, f)

更多信息: https://www.bfilipek.com/2017/06/cpp17-details-clarifications.html 看起来你实际上使用了 alignas 关键字,它会自动调用新的 new.

您需要在您的类型上指定 align as 关键字,然后像往常一样调用 new 和 delete。我在这里整理了一篇带有示例的文章:https://github.com/Twon/Alignment/blob/master/docs/alignment_in_C%2B%2B.md。一个例子是:

#include <memory>

int main() {
    class alignas(16) float4 {
        float f[4];
    }; 

    std::unique_ptr<float4 > aligned_vec4(std::make_unique<float4 >());
}

还有一个英特尔编译器示例,目前通过 aligned_new 扩展 header 提供此功能:https://software.intel.com/en-us/articles/aligned-operator-new-support-in-intel-c-compiler

我想问题是如何显式调用重载的 new,而目前所有答案都建议如何隐式调用。

我的解决方案(浮动对齐到 256 字节边界):

auto q = new (std::align_val_t(256)) float;
auto p = new (std::align_val_t(256)) float[10];

说明

我们转到 https://en.cppreference.com/w/cpp/language/new(“新表达式”)并导航到“Placement new”部分:

If placement_params are provided, they are passed to the allocation function as additional arguments

就是这样!

嗯,差不多。这里:https://en.cppreference.com/w/cpp/memory/new/operator_new 我们读到:

These allocation functions are called by new-expressions to allocate memory in which new object would then be initialized. They may also be called using regular function call syntax.

我对使用函数调用语法调用 operator new 的可能性很感兴趣。我认为没有人会这样做。让我们试试:

auto r = operator new (sizeof(float), std::align_val_t(256));
auto s = operator new[] (sizeof(float)*10, std::align_val_t(256)); // don't do it!!!

丑陋且危险,尤其是在类似数组的版本中,因为它没有对应于请求元素数量的参数的位置——它所需要的只是要分配的字节数,这可能需要考虑到一些对齐开销。