假设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。