代码之家  ›  专栏  ›  技术社区  ›  KeyC0de

正确分配具有新位置的数组

  •  0
  • KeyC0de  · 技术社区  · 6 年前

    我正在构建一个内存分配器并使用新的布局。 假设我想将10个元素“放置”到堆上已经分配的数组中。

    首先,regular new在堆上分配必要数量的字节,然后构造 WE 适当位置的物体。

    struct WE {
        WE() {
            std::cout << "WE default constructed\n";
        }
        ~WE() {
            std::cout << "WE default destructed\n";
        }
    
        double d;
        int i;
        char c;
    };
    

    代码编译和输出似乎是正确的,但我有一些疑问。

    // 1. allocate
    const int elements = 10;
    int nbytes = elements * sizeof(WE);
    char* memory = new char[nbytes];
    WE* pB = (WE*)memory;
    int step = sizeof(WE);
    // 2. construct
    for (int i = 0; i < nbytes; i += step)
        new (pB + i) WE();
    // 3. process
    for (int i = 0; i < nbytes; i += step)
        pB[i].i = i * 2;
    for (int i = 0; i < nbytes; i += step)
        std::cout << '[' << i << ']' << '=' << pB[i].i << '\n';
    // 4. destruct
    for (int i = 0; i < nbytes; i += step)
        pB[i].~WE();
    // 5. deallocate
    delete[] memory;
    pB = nullptr;
    memory = nullptr;
    

    假设我想在一个 sizeof(WE) 哪个是 16 (而不是在 alignof(WE) 哪个是 8 ). 此修改是否: alignas(sizeof(WE)) char* memory = new char[nbytes]; 足够做这个把戏吗?我也听说过 std::aligned_storage . 我不确定它是否能带来好处。(如果第二个问题把你弄糊涂了,或者我把第一部分的事情搞砸了,那就忘了它。)提前谢谢。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Daniel Langr    6 年前

    对于对象构造(新放置),可以按字节/字符顺序迭代:

    for (int i = 0; i < nbytes; i += step) new (memory + i) WE();
    

    或元素方面:

    for (int i = 0; i < elements; i++) new (pB + i) WE();
    

    alignof(std::max_align_t)

    operator new 不能直接为过度对齐的对象分配内存 std::aligned_storage 在这里没有帮助。从C++ 17,有特殊版本的 接受对齐信息的,请参见: https://en.cppreference.com/w/cpp/memory/new/operator_new

    推荐文章