Visual C ++中std :: vector :: erase()中的分段错误

时间:2011-09-22 14:09:48

标签: c++ visual-c++

我在std :: vector的擦除功能中遇到了分段错误,这让我很疯狂。我有以下代码:

std::map<uint32_t, std::vector<boost::uuids::uuid> >::iterator it
    = theAs.find(lSomeUint32);
if (it != theAs.end()) {
  std::vector<boost::uuids::uuid>& lIds = it->second; // vector contains one entry
  std::vector<boost::uuids::uuid>::iterator it2 = lIds.begin();
  while (it2 != lIds.end()) {
    if (*it2 == lSomeUuid) {
      lIds.erase(it2);
      break;
    }   
    ++it2;
  }   
}

在lIds.erase(it2)中,我遇到了分段错误。更准确地说,我在_Orphan_range中找到了一个分段错误(可以在c:\ Program Files \ Microsoft Visual Studio 10.0 \ VC \ include \ vector中找到),这是从擦除调用的。但我不知道为什么。向量和迭代器看起来不错。但是在_Orphan_range中,有些事情是完全错误的。虽然我的vector只包含一个项目,但是while循环执行了三次。在第三次运行中,变量_Pnext被破坏。

有人有想法吗?那太棒了!

大卫


不幸的是(或者幸运的是),上面的例子执行了独立的工作。但在我的大型软件项目中,它不起作用。

有人知道_Orphan_range执行失败的功能是什么吗?

3 个答案:

答案 0 :(得分:2)

从std :: vector中删除会使迭代器无效。见STL vector::erase 因此,在第一次调用擦除后,it2无效。唉,检查“(it2!= lIds.end())”将不成立。

将您的代码更改为:

if (*it2 == lSomeUuid) {
  it2 = lIds.erase(it2);
  break;
}  

答案 1 :(得分:0)

您与错误的end迭代器进行比较。

std::vector<boost::uuids::uuid>::iterator it2 = lIds.begin();
while (it2 != pIds.end()) {

注意lIdspIds。尝试在变量名称中使用更多字母,不要使用匈牙利表示法。你几乎立刻就抓住了Ids_ptr

答案 2 :(得分:-1)

不是你的

 "theAs.find(lSomeUint32);"

返回索引位置而不是Map :: iterator?我不确定这个。你能看看吗? find()函数返回aAs中lSomeUint32的位置,并返回字符串中lSomeUint32的位置(如果存在)。我想这就是你的擦除函数抛出错误的原因。它无法删除不存在或不在您的程序范围内的数据。

即使否则如果你的find()返回我想要的地图对象,除此之外还有一个简单的if结构来检查特定的find()是否返回任何对象,或者只是为了确保迭代器被赋值为在操作之前的价值。

只是一个建议。