【问题标题】:create a dynamic array while delaying object construction在延迟对象构造的同时创建动态数组
【发布时间】:2012-05-11 21:58:19
【问题描述】:

我希望能够“以某种方式”创建一个动态数组,它仍然可以让我使用 new 运算符构建它的元素。 这是我想要实现的目标:

A* a = new A[3]; //or any equivalent syntax 
new (&a[0]) A(myparams1); //placement new on first slot 
new (&a[1]) A(myparams2, ...); //placement new on 2nd slot 
new (&a[2]) A(myparams3, ...); //placement new on 3rd slot
delete[] a; //correct deletion of all elements

我知道这段代码可以工作(减去覆盖的 3 个元素),但我想避免在第一次调用 new[] 时创建 3 个默认的 a 元素。我在这里假设我会总是在调用delete[] 之前放置3 个元素。 我在想这样的事情可以通过对A::operator new[] 的智能调用来实现,但我不确定如何。 有谁有想法吗?主要是为了好奇

【问题讨论】:

  • 你不喜欢 std::vector 的哪些部分?
  • 第一行有语法错误,应该是A * a
  • 还可以在这里查看 C++11 向量如何使用 emplace_back push_back vs emplace_back 为您完成所有这些工作

标签: c++ arrays memory-management


【解决方案1】:

您只需要获取原始内存:

void* mem = ::operator new(capacity * sizeof(A));

这对于任何类型都需要对齐,包括A 的数组。现在您可以在其中构建:

for (std::size_t i = 0; i < capacity; ++i)
{
    void* addr = static_cast<char*>(mem) + i * sizeof(A);
    new (addr) A(x, y, z, ...);
}

破坏需要你显式调用它:

for (std::size_t i = 0; i < capacity; ++i)
{
    void* addr = static_cast<char*>(mem) + i * sizeof(A);
    static_cast<A*>(addr)->~A();
}

现在你可以释放原始内存了:

::operator delete(mem);

请注意,这些都不是异常安全的。这也是std::vector&lt;A&gt; 所做的,查看代码。

【讨论】:

  • 谢谢,这看起来确实不错。我只是想知道是否没有数组的变体?我认为这将是使用 ::operator new[] 和 ::operator delete[] 的最佳时机
  • @lezebulon:如果你想要一大块x 字节,你应该使用::operator new(或亲属)。如果你想要x 字节在一个数组中,那么当然可以使用::operator new[]。但请注意,这不是我们想要的,数组只是不必要的开销。
  • 我不确定我是否理解,使用 ::operator new[] 会发生什么变化?我很想使用它,因为我正在分配一个对象数组
  • @lezebulon:你可以很好地使用它,只是在概念上不匹配。在::operator new 调用期间,您没有分配数组,而是分配了一块内存。
【解决方案2】:

使用运算符 new。

A a* = (A*) ::operator new(sizeof(A) * 3);
new (&a[0]) A(/* whatever */);
//do stuff
a[0].~A();
::operator delete(a);

注意手动调用析构函数。当使用placement new时,不会自动调用析构函数,所以这取决于你。

【讨论】:

    【解决方案3】:

    您可以创建指针数组。

    A ** a = new A*[3]
    a[0] = new A;
    a[1] = new A;
    a[2] = new A;
    

    您需要在每个分配的元素上调用delete

    delete a[2];
    delete a[1];
    delete a[0];
    

    并删除数组本身delete[] a;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-05
      • 2022-08-22
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多