简体   繁体   English

std :: map :: erase和迭代器

[英]std::map::erase & iterators

I have some thing like this code: 我有一些类似下面的代码:

map<int, string> m;

m[1] = "a";
m[2] = "b";
m[3] = "a";
m[4] = "a";
m[5] = "e";
m[6] = "f";
m[7] = "g";
m[8] = "h";
m[9] = "i";

for (it1 = src.begin(); it1 != src.end(); ++it1) {

    for (it2 = it1; it2 != src.end(); ++it2) {
        if (it2 == it1) {
            continue;
        }

        if (it2->second == it1->second) {
            fprintf(stderr, "%u\n", it2->first);
            src.erase(it2);
        }
    }
}

I use map , because the elements is not always in this order (1, 2 ...) 我使用map ,因为元素并不总是按此顺序(1、2 ...)
So here is the question 所以这是问题

In some cases of map values, this code print this 在某些情况下,此代码将打印

2
3
4
6
7
8
9
5

How it is possible (skipping 5 ), if map sort by container in order 1, 2 ... and so on ? 如果地图按容器顺序1、2 ...依此类推,怎么可能(跳过5 )?

Your erase loop is off. 您的erase循环已关闭。 The typical idiom is this: 典型的成语是这样的:

for(std::map<K,V>::const_iterator it = v.begin(); it != v.end() /* not hoisted! */; /* no increment */ )
{
  // do something
  if (suitable_condition)
  {
    v.erase(it++);
  }
  else
  {
    ++it;
  }
}

Your code erroneously performs an increment on an invalid iterator (namely it2 after the erase ), which is undefined behaviour. 您的代码错误地对无效的迭代器执行增量(即, erase之后的it2 ),这是未定义的行为。

(For certain other container types, erase returns an iterator to the next valid element, so in those cases you would say it = v.erase(it) ; but the details of the best erasing pattern depend on the concrete container type.) (对于某些其他容器类型, erase将迭代器返回到下一个有效元素,因此在那种情况下,您会说它it = v.erase(it) ;但是最佳擦除模式的细节取决于具体的容器类型。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM