假设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;}
};
答案 0 :(得分:3)
您的班级T
存在两个主要问题:
delete
而非delete []
删除数组,提供未定义的行为使用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中。