为什么我需要手动删除vector中的指针?

dai*_*isy 4 c++ destructor memory-management

为什么我需要手动删除向量中动态创建的项目?当向量被删除时,为什么它们不会被删除或者它的析构函数被调用?

通常是这样的,但为什么需要?

vector<int*> v;
for (vector<int*>::iterator it = v.begin(); it != v.end(); ++it) 
{ 
   delete *it; 
}
Run Code Online (Sandbox Code Playgroud)

AnT*_*AnT 11

首先,将原始指针存储在向量中.这些指针只是指针.他们可以指向任何地方 它们可以指向无法删除的本地对象delete.即使它们指向动态创建的对象,也不一定意味着用户希望它们与向量一起死亡.矢量如何知道这一切?

这是对象所有权的问题.拥有该对象的人有责任及时删除.普通原始指针不表示所有权.这就是为什么vector无法对是否需要删除对象做出任何假设.如果要告诉向量它拥有动态对象,请使用相应的智能指针.

其次,请注意您的删除技术在一般情况下不一定安全.某些标准容器假定您存储在其中的数据始终有效.delete对每个向量元素执行操作时,向量中的数据将变为"无效"(指针变为不确定).这对矢量来说没问题.但是,在一个"聪明"的容器做这样的事情,像std::mapstd::unordered_set例如,可以并会导致问题.即使您之后立即销毁容器本身,容器的销毁算法也可能需要分析(比较,散列等)各个元素的值.而你刚刚用你的周期杀死它们.

智能指针自然会解决这个问题.但是如果你必须使用手册delete存储在标准容器中的原始指针,那么更好的步骤就是这样

  1. 检索元素的值i并将其存储在指针中p
  2. i从容器中删除元素
  3. delete p

最后,您最终得到一个空容器和delete数据.同样,您的方法适用于简单的序列,例如std::vectorstd::list,但不要使用有序或散列的序列.


Pup*_*ppy 6

因为当你完成时,语言无法知道你是否需要它们保持活力.如果你插入一些指向堆栈对象或类似的东西怎么办?繁荣.

但是,这可以通过使用智能指针来解决,智能指针实现适当的自动销毁策略.unique_ptr并且shared_ptr是最常见和最有用的.