c++不需要删除迭代器
C++ does the iterator need to be deleted?
我有一个关于内存释放的问题
我正在我的一个程序中迭代一个向量。像这样:
// 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;
还是因为释放了迭代器,所以不需要释放迭代器?
只能对迭代器保存的对象调用delete,而不能对迭代器本身调用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会生成编译器错误(取决于编译器/实现等)
根据我的经验,你永远不会删除迭代器。最重要的是,迭代器只需要很少量的内存
迭代器不拥有(观察)。它们是为容器"产生"的,但实际上并不是保存内存的对象。因此,您不仅不需要,而且一定不能删除它们。
另一方面,当容器为其持有的对象分配内存时,可以并且应该通过迭代器释放。一个示例
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
}
除了其他人已经解释过的关于迭代器的一般规则之外,在你放在那里的代码的情况下,迭代器是一个堆栈变量,其作用域是声明它的块的局部(这几乎总是你声明迭代器的方式),因此删除它并不比删除任何其他堆栈变量更有意义,因为当它超出作用域时被清理。你只在分配了new
的东西上调用delete
。
这里也有些相关:您写了vector<int>* v = new vector<int>()
,这意味着v是一个指针,并在"堆"(自由存储)上分配,因此您需要显式地删除它。但是在你的例子中,你只在本地使用v
,所以你根本没有理由使用指针,你不应该使用一个。只需编写std::vector<int> v;
并直接使用它:it = v.begin()
,就像@keyser解释的那样,就像您实际使用迭代器一样。当您这样做时,您不再调用delete v;
, v
将在超出作用域时自动清理,就像it
现在被清理一样。
也许您需要阅读一些关于RAII的内容,这是优秀c++编程的基础之一。如果你有Java或Delphi或c#背景,这是一个新颖的概念,因为在这些语言中,你得到的都是对堆上对象的引用(或者编译器和运行时决定把它们放在哪里),但在c++中不是这样。您应该学会在c++代码中尽可能多地利用这个特性。在c++中,指向对象的指针应该是例外,而不是规则。
- 使用迭代器 C++ 删除矢量中的重叠字符串
- C++:在进行切片时对迭代器的约定,特别是对于访问最后一个元素并最终将其删除
- 如何使用擦除和迭代器来删除二维向量中的项目
- 如果我有一个指向矢量元素的指针,而不是迭代器,如何删除它?
- c++ 在循环中删除迭代器(映射的映射)
- 从矢量C++中删除时,矢量迭代器不可取消引用
- 为什么擦除-删除成语不适用于反向迭代器
- 通过反向迭代器从矢量快速删除
- debug断言矢量迭代器不可用find_if删除
- 如何在不使用循环或迭代器的情况下检查所有列表元素并在满足条件时删除一个
- 如何在给定迭代器列表的情况下从向量中删除元素
- 射击时从列表中删除外星人 - 找出循环;"表达式:无法递增结束列表迭代器"
- 仅通过迭代器删除 STL 容器元素
- 另一个迭代器引用的对象被另一个迭代器删除
- 使用迭代器删除对象
- C++设置迭代器删除
- 使用迭代器删除元素,而不知道向量
- 在c++ 11基于范围的for循环中,通过迭代器删除字符串中的空白
- c++使用迭代器删除空白会失败
- 在循环中使用迭代器删除unordered_set中的元素