C ++是否需要删除迭代器?

时间:2014-05-10 07:41:48

标签: c++ memory

我有一个关于内存释放的问题

我在我的一个程序中迭代一个向量。像这样:

// init vector
vector<int>* v = new vector<int>();
// iterate
for (vector<Column>::iterator it = v->begin(); it != v->end(); ++it) {
    // do something with it
}
// delete vector
delete v;

但我不确定,如果我应该写:

// init vector
vector<int>* v = new vector<int>();
// iterate
vector<Column>::iterator it = v->begin()
for (; it != v->end(); ++it) {
    // do something with it
}
delete it;
// delete vector
delete v;

还是释放了不必要的迭代器,因为释放了迭代器?

4 个答案:

答案 0 :(得分:2)

你只对迭代器所持有的对象调用delete,而不是迭代器本身;使用您的代码作为示例(但稍作修改):

std::vector<int*> *v = new std::vector<int*>();
for (int i = 0; i < 10; ++i) {
    v->push_back(new int(i));
}
std::vector<int*>::iterator it = v->begin();
for (; it != v->end(); ++it) {
    // do something with it
    delete *it; // <- notice the deference to delete the underlying int 
    //delete it; // causes compiler error (expected pointer)
}
// delete vector
delete v;

在迭代器类型上调用delete应该会产生编译器错误(取决于编译器/实现等)。

答案 1 :(得分:1)

根据我的经验,你永远不会删除迭代器。最重要的是,迭代器只需要一点点内存。

答案 2 :(得分:1)

迭代器不拥有(观察)。他们是'#34;生产&#34;对于容器,但实际上不是保存内存的对象。因此,您不仅不需要,而且也不能删除它们。

另一方面,当容器为其所拥有的对象分配内存时,您可以通过迭代器解除分配。一个例子

vector<int*> v(10);
std::generate(v.begin(), v.end(), []() { return new int; });

然后,为v中的所有对象释放内存的一种方法是

for (auto i = v.begin(); i != v.end(); i++)
{
    delete *i; // deleting through the iterator - we're not deleting THE iterator
}

答案 3 :(得分:1)

除了其他人已经解释过的关于迭代器的一般规则之外,对于你所放置的代码,迭代器是一个堆栈变量,其范围是声明它的块的本地(这是几乎总是如何声明迭代器),因此删除它不会比删除任何其他超出范围时被清理的堆栈变量更有意义。您只需对delete分配的内容发送new

这里也有点相关:你写了vector<int>* v = new vector<int>(),这意味着v是一个指针,并在&#34;堆&#34;上分配。 (免费商店)所以你需要明确删除它。但是在你的例子中,你只在本地使用v,所以你根本没有理由使用指针而你不应该使用指针。只需编写std::vector<int> v;并直接使用它:it = v.begin(),正如@keyser所解释的那样,就像你实际使用迭代器一样。执行此操作后,您不再致电delete v; v会在超出范围时自动清理,就像现在清除it一样。

也许你需要阅读RAII,这是良好的C ++编程的基础之一。如果您来自Java或Delphi或C#背景,那么这是一个新概念,因为在这些语言中,您获得的是对堆上对象的引用(或者编译器和运行时决定放置它们的地方) )但在C ++中并非如此。您应该学习在C ++代码中尽可能多地利用此功能。在C ++中,指向对象的指针应该是例外,而不是规则。