如何在 C++17 中调用重载对齐的 new 和 delete 运算符?
How to call the overloaded aligned new and delete operators in `C++17`?
从 cppreference 我们可以看到 new
和 delete
以及 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!!!
丑陋且危险,尤其是在类似数组的版本中,因为它没有对应于请求元素数量的参数的位置——它所需要的只是要分配的字节数,这可能需要考虑到一些对齐开销。
从 cppreference 我们可以看到 new
和 delete
以及 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!!!
丑陋且危险,尤其是在类似数组的版本中,因为它没有对应于请求元素数量的参数的位置——它所需要的只是要分配的字节数,这可能需要考虑到一些对齐开销。