既然std::array不允许更改其分配器,是否有办法确保指向数据地址的指针是对齐的?
例如,在GNU g ++ 4.8.4和6.1.0中,代码如下
#include <array>
#include <iostream>
int main(void)
{
std::array<bool, 10> a;
std::array<char, 10> b;
std::array<int,10> c;
std::array<long long, 10> d;
std::array<float, 10> e;
std::array<double, 10> f;
std::cout << "array<bool,10>.data() = " << a.data() << std::endl;
std::cout << "array<char,10>.data() = " << (void*) b.data() << std::endl;
std::cout << "array<int,10>.data() = " << c.data() << std::endl;
std::cout << "array<long long, 10>.data() = " << d.data() << std::endl;
std::cout << "array<float, 10>.data() = " << e.data() << …Run Code Online (Sandbox Code Playgroud) C++17 引入了一种新类型 ,std::byte所以现在我们终于有了一个一等公民类型来表示内存中的字节。除了标准中的新奇之外,对象创建、生命的开始和结束、别名等的 C++ 规则在大多数情况下都相当复杂且不直观,所以每当我觉得std::byte是正确的工具时,我也会感到紧张和不愿使用它,因为害怕无意中召唤出未定义行为炎魔。
一种这样的情况是用于放置 new 的缓冲区:
#include <memory>
#include <cstddef>
#include <type_traits>
struct X { double dummy[4]; char c; };
auto t1()
{
// the old way
std::aligned_storage_t<sizeof(X)> buffer;
X* x = new (&buffer) X{};
x->~X();
}
auto t2()
{
// the new way?
std::byte buffer[sizeof(X)];
X* x = new (&buffer) X{};
x->~X();
}
Run Code Online (Sandbox Code Playgroud)
是t2完全安全和等效的t1?
针对对齐问题,如何处理:
auto t3()
{
alignas(X) std::byte buffer[sizeof(X)];
X* x = new (&buffer) X{};
x->~X();
}
Run Code Online (Sandbox Code Playgroud)