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

时间:2014-01-23 15:00:23

标签: c++ pointers memory-management vector

假设T包含一个数组,其大小可能因初始化而异。我正在传递一个指向矢量的指针,以避免复制所有数据,并按如下方式初始化:

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

退出时,一个delete是向量的元素。如果T中包含的数据也是指针,即使存在良好的析构函数,是否存在内存丢失的风险?例如

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

2 个答案:

答案 0 :(得分:3)

您的班级T存在两个主要问题:

  • 使用delete而非delete []删除数组,提供未定义的行为
  • 您没有实现(或删除)复制构造函数和复制赋值运算符(根据Rule of Three),因此存在两个对象都试图删除相同数组的危险。

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

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

答案 1 :(得分:2)

答案是:不要。

使用

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);

这两者都以最小的开销(特别是最后一个)为你做所有事情。

请注意,使用emplace_back参数调用new并不像您希望的那样异常安全,即使结果元素是智能指针也是如此。为此,您需要使用{C ++ 14中的std::make_unique。存在各种实现,并且它不需要特殊的东西。它刚刚从C ++ 11中省略,并将被添加到C ++ 14中。