调用擦除后迭代器无效

发布于 2025-01-06 08:09:55 字数 515 浏览 0 评论 0原文

我有点困惑。我了解到或被告知的是,如果调用擦除,向量的迭代器将变得无效。但为什么下面的代码有效。它使用 g++ 编译并在 Linux 中运行。

#include <vector>
#include <iostream>

using namespace std;

int main() {
  vector<int> vec;
  vec.push_back(1);
  vec.push_back(2);
  vec.push_back(3);

  vector<int>::iterator it = vec.begin();
  ++it;
  vector<int>::iterator it2;

  it2 = vec.erase(it);
  cout << "it: " << *it << endl;
  cout << "it2: " << *it2 << endl;
}

感谢您的任何反馈!

I am confused a bit. What I have learned or been told is that an iterator of a vector becomes invalid if erase is called. But why the code below works. It is compiled using g++ and run in Linux.

#include <vector>
#include <iostream>

using namespace std;

int main() {
  vector<int> vec;
  vec.push_back(1);
  vec.push_back(2);
  vec.push_back(3);

  vector<int>::iterator it = vec.begin();
  ++it;
  vector<int>::iterator it2;

  it2 = vec.erase(it);
  cout << "it: " << *it << endl;
  cout << "it2: " << *it2 << endl;
}

Thanks for any feedbacks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

祁梦 2025-01-13 08:09:55

来自 http://www.cplusplus.com/reference/stl/vector/erase/< /a> (不是世界上最好的 C++ 参考):

这将使所有迭代器和对位置(或第一个)及其后续元素的引用无效。

所以是无效的;使用它会导致未定义的行为。事实上,你碰巧得到了你所期望的东西,这纯粹是运气不好。

From http://www.cplusplus.com/reference/stl/vector/erase/ (not the world's best C++ reference):

This invalidates all iterator and references to position (or first) and its subsequent elements.

So it is invalid; using it results in undefined behaviour. The fact that you happen to get what you expect is pure bad luck.

后eg是否自 2025-01-13 08:09:55

你正在做的是未定义的行为,并且它“有效”完全是偶然的。您不能也决不能永远依赖它,因为它几乎可以做任何事情。它的行为没有定义。

What you're doing is Undefined Behaviour, and that it "works" is entirely accidental. You cannot and must not ever rely on this, because it could do just about anything. The behaviour of it is not defined.

远山浅 2025-01-13 08:09:55

作为实现细节,vector::iterator 很容易是 int*。我认为在 g++ 中,它是一个围绕 int* 的非常薄的包装器。如果是这种情况,那么擦除三元素向量的中间元素意味着 it 的指针数据成员仍指向与删除的元素相同的地址,当然该地址将包含该值之前紧随其后,并且也被 it2 有效引用。

该标准不保证 it 仍会引用任何内容,这就是为什么您不能依赖在这里观察到的行为。但它解释了你所看到的。当您取消引用时,实现几乎必须竭尽全力才能使其他事情发生。但编译器每天都会不遗余力:例如,调试库的版本,并且一些优化技术依赖于代码正确的假设。

As an implementation detail, vector<int>::iterator can easily be int*. I think in g++ it's a very thin wrapper around an int*. If that's the case, then erasing the middle element of a three-element vector means that the pointer data member of it is left pointing at the same address as the element removed, which of course will contain the value that previously was straight after it, and which is also validly referred to by it2.

The standard does not guarantee that it will still refer to anything, which is why you can't rely on the behavior you've observed here. But it explains what you've seen. An implementation pretty much has to go out of its way to make anything else happen when you dereference it. But compilers do go out of their way every day: debugging versions of the libraries for example, and some optimization techniques rely on assumptions that your code is correct.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文