繁体   English   中英

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

[英]Why do I need to delete pointers from vector manually?

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

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

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

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

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

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

智能指针自然会解决这个问题。 但是,如果必须对存储在标准容器中的原始指针使用手动delete ,则可以采用更好的步骤顺序

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

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

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

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

不会调用析构函数,因为指针不拥有它指向的对象。

在C ++ 11中, std::unique_ptr<T>确实拥有它指向的对象。 在这种情况下,释放指针时会调用析构函数,这可能是您想要的行为。 (如果你没有C ++ 11编译器但是有一个合理的最新的C ++ 11之前的编译器,那么unique_ptr仍然是TR1的一部分。)

vector的实现只是为了删除它的内存。 指针没有解构器。 在C ++中,没有垃圾收集或逻辑可以看到它是指针并且递归删除它。

如果您想参加下一次ISO会议并提出建议,请成为我的客人,但对我而言,我只是将其置于inline函数中:

template<class T>
public static inline void deleteVectorPointer(std::vector<T*> v)
{
    for (vector<T*>::iterator i = v.begin(); i != v.end(); i++)
    {
        delete *i;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM