使用 std::vector<T*控制内存>



假设T包含一个数组,其大小可能会根据初始化而变化。我正在将指针传递给向量,以避免复制所有数据,并以下初始化:

for(int i=10; i < 100; i++)
    std::vector.push_back(new T(i));

在退出时,一个 delete s向量的元素。如果T中包含的数据也是指针,即使有良好的破坏者,是否存在记忆损失的风险?例如

template<class M> class T{
    M * Array;
public:
    T(int i) : Array(new M[i]){ }
    ~T(){ delete Array;}
};

您的类T有两个主要问题:

  • 您使用delete而不是delete []删除数组,给出不确定的行为
  • 您不实现(或删除)复制构造函数和复制分配运算符(根据三个规则),因此两个试图删除同一数组的对象都有危险。

可以通过使用std::vector而不是编写自己的版本来轻松解决这两个。

最后,除非您有充分的理由(例如多态性)存储指针,请使用std::vector<T>,以便您无需手动删除元素。在删除元素或离开向量范围时,很容易忘记这样做,尤其是在抛出异常时。(如果您确实需要指针,请考虑unique_ptr自动删除对象)。

答案是:不要。

要么使用

std::vector<std::vector<M>> v;
v.emplace_back(std::vector<M>(42)); // vector of 42 elements

或(yuck)

std::vector<std::unique_ptr<M[]>> v;
// C++11
std::unique_ptr<M[]> temp = new M[42]; // array of 42 elements
v.emplace_back(temp);
// C++14 or with handrolled make_unique
v.emplace_back(std::make_unique<M[]>(42);

两者都用最小的头顶为您完成一切(尤其是最后一个)。

请注意,即使结果元素将是智能指针,使用new参数调用emplace_back也不像您想要的那样存在。为此,您需要使用C 14中的std::make_unique。存在各种实现,它不需要特别。它只是从C 11中省略了,将添加到C 14。

最新更新