c++ - 奇怪的迭代器行为

标签 c++ iterator

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    string s = "Haven't got an idea why.";
    auto beg =  s.begin();
    auto end = s.end();
    while (beg < end)
    {
        cout << *beg << '\n';
        if (*beg == 'a')
        {//whithout if construct it works perfectly
            beg = s.erase(beg);
        }
        ++beg;
    }
    return 0;
}

为什么如果我从这个字符串中删除一个或多个字符,这个代码就会中断?我想这与在比结束迭代器更高的地址创建删除操作后返回的迭代器有关,但我不确定,这肯定不是正确的行为。或者是?

最佳答案

这段代码有几个问题。

  1. 不要缓存 s.end() 的值;它会随着您删除元素而改变。
  2. 不要使用 beg < end .惯用的方法是写 beg != end .如果您尝试迭代过去 end ,结果未定义,字符串库的调试版本可能会故意使您的进程崩溃,因此使用 < 是没有意义的.
  3. s.erase(beg)返回的迭代器可能是 s.end() , 在这种情况下 ++beg带你走到尽头。

这是(我认为)正确的版本:

int _tmain(int argc, _TCHAR* argv[])
{
    string s = "Haven't got an idea why.";
    for (auto beg = s.begin(); beg != s.end();)
    {
        cout << *beg << '\n';
        if (*beg == 'a')
        {//whithout if construct it works perfectly
            beg = s.erase(beg);
        }
        else
        {
            ++beg;
        }
    }
}

编辑:我建议接受 FredOverflow 的回答。它比上面的更简单、更快。

关于c++ - 奇怪的迭代器行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3052298/

相关文章:

c++ - 非默认可构造元素的最后一个元素

c++ - 预测迭代器

java - 当Iterator不支持remove()时如何动态修剪Java List?

c++ - 我需要将 strtol 的结果转换为 int 吗?

c++ - Qt槽没有激活

c++ - IOS 删除 native 库中分配的内存

c++ - 关于 NTFS Change Journal USN 记录的问题

c++ - 如何使用 C++ 迭代器调用 Win32 API 函数 `WriteFile()`?

java - 使用递归通过迭代器查找字符串的排列

c++ - 初始化构造函数的区别