Почему установка указателя итератора вызывает ошибку сегментации? - PullRequest
1 голос
/ 22 сентября 2011

Итог, почему итератор может вызвать ошибку сегментации? Обратите внимание, я набираю здесь соответствующие части моего кода, а не копирую вставку. Если при компиляции произошла ошибка, обратите внимание, но не считайте ее источником моей проблемы.

В моем коде у меня есть карта ящиков для бисера:
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
        .
        .
        .
      }
    }
  }
}

По какой-то причине у меня ошибка сегментации. То, что я получил так далеко, это:

  • ошибка сегментации является причиной из-за увеличения интегратора.
  • размер коробки 2.
  • это не первый ящик, который я тестирую (не считал их, но он работает некоторое время).
  • Я абсолютно не знаю, как получить доступ ко второму элементу в блоке (первый я могу использовать итератор, так как я не увеличиваю его.
  • Это ошибка вывода из GDB:

    0 0x00002aaaaab43c65 в std :: _ Rb_tree_increment (std :: _ Rb_tree_node_base *) () из /usr/lib64/libstdc++.so.6 1 0x000000000041a28e в операторе ++ (this = 0x63d7c0) в /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_tree .h: 265

Буду признателен за любую помощь, спасибо.

Edit: Решено, вроде.

Пытаясь свести ошибку к минимальному рабочему примеру, я удалил все эти строки и переписал их, и теперь все выглядит хорошо. Я все еще заинтересован в таком случае, хотя:

Если хотите, я могу задать вопрос: Когда инкрементный итератор вызовет ошибку сегментации в c ++?

Ответы [ 3 ]

5 голосов
/ 22 сентября 2011

Отвечать на ваше редактирование можно только одним способом:

Если хотите, я могу задать вопрос: когда инкрементный итератор вызовет ошибку сегментации в c ++?

Увеличение итератора вызовет ошибку сегментации, только если он используется неправильно.

Вот и все.

Стандарт не перечисляет случаи, в которых код должен происходить с ошибкой, он только перечисляет, что должно произойти, когда код используется правильно . Когда вы используете неправильно , это просто неопределенное поведение, и может произойти любое из миллиона событий, включая, но не ограничиваясь, ошибки сегментации.

Если приращение вашего итератора дало вам ошибку, это либо потому, что:

  • итератор уже указал на конец набора или
  • итератор указал за пределы набора на переменную, которая вышла из области видимости, или, возможно, итератор вообще никогда не был инициализирован.

Но ошибки сегментации случаются, когда у вас неопределенное поведение. И это, по определению, делает невозможным сказать вам, какие случаи вызовут ошибку сегментации.

3 голосов
/ 22 сентября 2011

В этих строках присутствует как минимум одна ошибка:

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

Предполагая, что beadsBoxes и nextBoxes - объекты стандартных типов контейнеров, вы используете итератор неправильно.

bit2 представляется итератором, указывающим на элементы beadsBoxes. Но вы сравниваете это с концом nextBoxes. Если beadsBoxes[2] и nextBoxes[2] представляют разные объекты, вы не можете этого сделать.

1 голос
/ 23 сентября 2011

Первое, что вам нужно исправить, это getBox.Он не возвращает значение, поэтому при его вызове происходит неопределенное поведение.Добавьте return out; в конце.

...