【问题标题】:Why does set iterator pointer cause segmentation fault?为什么设置迭代器指针会导致分段错误?
【发布时间】:2011-11-22 21:20:14
【问题描述】:

底线,为什么迭代器会导致分段错误? 请注意,我在此处键入我的代码的相关部分,而不是复制粘贴。如果编译中有错误,请注意但不要认为这是我的问题的根源。

在我的代码中,我有一张珠子盒地图:
map<vector<int>,set<shared_ptr<bead> > > > nextBoxes;

每个珠子都有一个vec pos 成员,而该成员又具有:

  class vec{
  double x;
  double y;
  double z;
  .
  .
  .
  vector<int> getBox();
  .
  .
  .
}

vector<int> vec::getBox(){
  vector<int> out(3,0);
  extern double boxSize;
  out[0] = x/boxSize;
  out[1] = y/boxSize;
  out[2] = z/boxSize;
  return out;
}

我用一个很简单的方法把珠子打进盒子里

extern vectrot<shared_ptr<bead> > beads;
for (int i = 0; i < beads.size(); i++){
  vector<int> t = beads[i]->pos.getBox();
  nextBoxes[t].insert(beads[i]);
}

在代码的其他地方,珠子的pos 值可能会发生变化,我会在本地更新这些框。

我使用以下循环遍历盒子和珠子:

map<vector<int>,set<shared_ptr<bead> > >::iterator mit = nextBoxes.begin();
extarn vector<vector<int> >::targets; //holds a vector of a 1, -1 and 0 vectors of distance from the box
extern int boxNum;
while (mit != nextBoxes.end()){
  vector<int> t1 = mit->second();
  set<shared_ptr<bead> >::iterator bit1 = mit->second.begin();
  set<shared_ptr<bead> >::iterator bit2;
  while (bit1 != mit->second.end()){ 
    shared_ptr<bead> b = *bit++;
    vector<int> t2(3,0);
    for (int i = 0; i < 13 i++){//13 is the size of the targets index.
      for (int j = 0; j < 3; j++){
        t2[j] = t1[j] + targets[i][j];
        if (t2[j] >= boxNum) t2[j] -= boxNum;
        if (t2[j] < 0 ) t2[j] += boxNum;
      }
      bit2 = beadsBoxes[t2].begin();
      while (bit2 != nextBoxes[t2].end()){
        shared_ptr<bead> b2 = *bit2++//the segmentation fault is here
        .
        .
        .
      }
    }
  }
}

由于某种原因,我遇到了分段错误。到目前为止我得到的是:

  • 分段错误是由于 interator 的增量引起的。
  • 框大小为 2。
  • 这不是我要测试的第一个盒子(没有计算它们,但它运行了一段时间)。
  • 我完全不知道如何访问框中的第二个元素(第一个我可以使用迭代器,因为我不递增它。
  • 这是来自 gdb 的输出错误:

    0 0x00002aaaaab43c65 in std::_Rb_tree_increment(std::_Rb_tree_node_base*) () 来自 /usr/lib64/libstdc++.so.6 1 0x000000000041a28e 在 /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_tree 的 operator++ (this=0x63d7c0) .h:265

如果有任何帮助,我将不胜感激,谢谢。

编辑: 解决了,有点

试图将错误减少到最小的运行示例,我删除了所有这些行并重写了它们,现在看起来一切正常。不过,我仍然对这种情况感兴趣:

如果你愿意,我可以重新提问: 迭代器增量何时会导致 c++ 中的分段错误?

【问题讨论】:

  • "如果编译有错误,请注意,但不要认为是我的问题的根源。" - 如果您向我们展示的代码无法编译,我们没有办法猜测真正的问题是什么。
  • 我没有看到bit2 的声明,也没有看到beadsBoxes 的声明,所以我真的不能说为什么指示的行出错了。请将您的程序简化为仍然显示问题的最简单形式,然后将该程序复制粘贴到您的问题中。在减少程序的过程中,您可能会自己发现错误。有关这种缩减和粘贴技术的更多信息,以及它为何如此重要,请参阅sscce.org
  • @jalf,这个想法是从一开始就不是编译错误
  • @Rob:我希望我能减少它,我不知道,但这是为什么,我担心它源于我不明白的 c++ 中固有的东西然而。我希望这是迭代器的一些众所周知的问题。
  • @Yotam:但我的意思是,如果您向我们展示不起作用的代码,并告诉我们忽略使其不起作用的事情,那么我们就不可能告诉您原因它不起作用!如果您想要一个有用的答案,您需要向我们展示代码,其中 only 问题是您需要帮助的问题。

标签: c++ iterator segmentation-fault set


【解决方案1】:

以唯一可能的方式回答您的编辑:

如果你愿意,我可以再问一个问题:迭代器增量何时会导致 c++ 中的分段错误?

增加一个迭代器只有在使用不正确的情况下才会导致分段错误。

就是这样。

该标准没有列出代码必须出现段错误的情况,它只列出了代码正确使用时应该发生的情况。当您不正确地使用它时,它只是未定义的行为,可能会发生一百万种情况中的任何一种,包括但不限于分段错误。

如果增加你的迭代器给你一个段错误,那是因为:

  • 迭代器已经指向集合的末尾,或者
  • 迭代器指向集合外部,指向一个超出范围的变量,或者迭代器根本没有被初始化。

但是当您有未定义的行为时,就会发生分段错误。而且,根据定义,无法告诉您哪些情况会触发分段错误。

【讨论】:

    【解决方案2】:

    这些行中至少存在一个错误:

      bit2 = beadsBoxes[t2].begin();
      while (bit2 != nextBoxes[t2].end()){
        shared_ptr<bead> b2 = *bit2++//the segmentation fault is here
    

    假设beadsBoxesnextBoxes 是标准容器类型的对象,那么您错误地使用了迭代器。

    bit2 似乎是一个指向beadsBoxes 成员的迭代器。但是,您将它与nextBoxes 的结尾进行比较。如果beadsBoxes[2]nextBoxes[2] 代表不同的对象,则不能这样做。

    【讨论】:

    • 你是对的,但是。 1. 这个错误没有出现在我的代码中(据我所知)。 2.当我尝试访问bit2而不增加它时,这个错误会产生分段错误...
    • 1) 它出现在您的代码中,如问题中所述。我无法评论任何其他代码。 2)根据bit2的实现,错误很可能发生在operator++而不是operator*
    • 至于1你是对的,我只声明它没有出现在我的代码中。至于2,你能给我举个例子吗?我问这个是因为根据我的经验,我只遇到了我所说的。 (我的经验主要是科学编程,所以我不认为这是真正的经验)。
    【解决方案3】:

    您应该修复的第一件事是getBox。它不返回值,因此在调用它时会发生未定义的行为。在末尾添加return out;

    【讨论】:

    • 好点,已修复。我想知道,在这种情况下会发生什么?我认为代码不会编译
    猜你喜欢
    • 1970-01-01
    • 2014-01-10
    • 2013-10-25
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多