C++ 在C++;?

C++ 在C++;?,c++,memory,vector,containers,delete-operator,C++,Memory,Vector,Containers,Delete Operator,我搜索了StackOverflow,但找不到这个问题的答案 假设我有一个std::vector vector\u day,也就是说,一个指向day对象的指针向量。现在我将向后推到向量日许多元素: vector_day.push_back(new Day(12)); vector_day.push_back(new Day(99)); vector_day.push_back(new Day(71)); ... 现在,在某个时刻,我不再需要vector\u day。释放内存的正确方法是什么 这是

我搜索了StackOverflow,但找不到这个问题的答案

假设我有一个
std::vector vector\u day
,也就是说,一个指向
day
对象的指针向量。现在我将
向后推
向量日
许多元素:

vector_day.push_back(new Day(12));
vector_day.push_back(new Day(99));
vector_day.push_back(new Day(71));
...
现在,在某个时刻,我不再需要
vector\u day
。释放内存的正确方法是什么

这是正确的方法:

for (std::vector<Day *>::iterator i = vector_day.begin(); i != vector_day.end(); ++i) {
    delete *i;
}
for(std::vector::iterator i=vector_day.begin();i!=vector_day.end();++i){
删除*i;
}

这不会使每次删除时的向量无效吗?我很困惑。

如果你不是绝对需要的话,最好的方法就是不要把指针放在向量的第一位

但是如果你真的需要一个指针向量,那么你做的方式就很好了(但是
.clear()
向量后缀,如果它不会被立即销毁,这样它就不会充满悬空的指针)

声明

delete *it;

对迭代器没有影响。它不会更改迭代器、使迭代器无效或从集合中删除迭代器引用的指针。它所做的只是释放迭代器引用的指针指向的内存。指针本身必须单独从集合中删除。

从数组中添加或删除元素的操作可能会使迭代器无效,请查看文档以了解不同容器类型的特定规则。使用
delete
,您将对数组元素中包含的数据进行操作,而不是对数组的形状进行操作。迭代器遍历容器的形状,它们不关心容器的内容。

首先,您从
i
切换到
it
,但我认为这只是一个输入错误


但是为了回答你的问题,不,没关系。您不是在更改
,而是在更改
*它

您可能应该使用某种托管指针,很可能是共享指针

如果你删除了这个向量,而其他人仍然持有其中一个指针,如果他们试图去引用它,你会得到一些非常恶劣的行为。共享指针可以帮你省去那些麻烦


如果您可以保证删除向量后不会有任何其他内容引用指针,那么您仍然可以从使用自动指针中获益。当向量被销毁时,它将为您管理释放。开销很小,让你的生活轻松多了。

很好。您正在删除
*i
(向量元素指向的对象)而不是
i
(向量元素),因此向量不会失效


参见开发人员还想删除所有<代码> i>代码> s,并在循环之后找到它的解决方案(<代码> VC++).< /P> < P>另一个C++的方式是定义一个辅助结构:

struct delete_ptr { // Helper function to ease cleanup of container
    template <typename P>
    void operator () (P p) {
        delete p;
    }
};

一般来说,C++中应该尽可能地隐藏内存管理,以避免内存错误。除非您大量复制指针,并且非常关心性能,否则我只会使用共享的ptr

这是Tr1标准的一部分,在大多数现代C++编译器中是可用的(箱中),并且对于火和忘记内存管理来说是很好的。

< P>救援!
做您需要的事情,而不需要迭代和删除std::vector的内容

这是我不久前在处理相同问题时编写的一个方便的类。我正在将一些代码从旧的基于RogueWave的向量和列表转换为基于STL的向量和列表,并且需要一些方法来模拟RW的clearAndDestroy()指针列表方法。clearAndDestroy()方法可以被重写以处理不同的结构类型(为了简洁起见,我这里只包括了vector)

类StlUtils
{
公众:
/**
*此方法提供了一种销毁std::vector的模板化方法
*满是指针。它基本上是RW的替代品
*vector类的clearAndDestroy方法。列表参数为
*返回空的。
*
*@param list要销毁的指针列表。
*/
模板静态无效清除和销毁(
标准::向量和项目列表)
{
对于每个(itemList.begin(),itemList.end(),
stl_deleter());
itemList.clear();
}
私人:
/**
*用于clearAndDestroy()的模板化成员函数
*方法。它提供了每个用户执行以下操作所需的方法:
*实际删除。
*/
模板结构stl\U删除器
{
void运算符()(T*x){
如果(x!=NULL)
删除x;
}
};
};

另一种迭代+删除的方法是使用
while(!empty)
循环。 这种技术的优点是先从容器中删除元素,然后再删除。这对于任何容器都是安全的:

while (!vector_day.empty()) {
    Day* day = vector_day.back();
    vector_day.pop_back();
    delete day;
}

可能是RC的复制品-不是真的,这是完全不同的。不要像那样放指针。如果在向量中的时间和删除所有内容的位置之间抛出异常会怎么样?你会跳过它,然后泄漏。使用智能指针或指针容器,不要使用原始指针。感谢您的解释。所以当向量超出范围时,指针将自动删除,对吗?@bodacido:right。如果在
向量
超出范围之前调用
delete*it
,不要担心调用
clear()
。我纠正了
it
用于
I
的错误。谢谢你发现了。如果我在循环中做了
I=0xAABBCCDD
,这显然改变了
I
,而不是
it
,这会使向量无效吗?我现在更了解无效。谢谢你的回答!您可以删除空指针(这将不起任何作用),因此实际上不需要if
class StlUtils
{
   public:

      /**
       * This method provides a templated way to destroy a std::vector
       * full of pointers.  It is basically a replacement for the RW
       * vector class' clearAndDestroy methods.  The list argument is
       * returned empty.
       *
       * @param list the list of pointers to be destroyed.
       */
      template<class T> static void clearAndDestroy(
         std::vector<T*> &itemList)
      {
         for_each(itemList.begin(), itemList.end(),
                  stl_deleter<T>());
         itemList.clear();
      }

   private:

      /**
       * Templated member function for use with the clearAndDestroy()
       * method.  It provides the method needed by for_each to do the
       * actual deletion.
       */
      template<class T> struct stl_deleter
      {
         void operator() (T* x) {
            if (x != NULL)
               delete x;
         }
      };
};
while (!vector_day.empty()) {
    Day* day = vector_day.back();
    vector_day.pop_back();
    delete day;
}