Ошибка сегментации в std :: vector :: erase () в Visual C ++ - PullRequest
1 голос
/ 22 сентября 2011

У меня ошибка сегментации в функции стирания 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 что-то идет не так.Цикл while выполняется там три раза, хотя мой вектор содержит только один элемент.При третьем запуске переменная _Pnext ломается.

У кого-то есть идея?Это было бы здорово!

Дэвид


К сожалению (или, к счастью, к счастью), приведенный выше пример выполнял отдельные работы.Но в моем большом программном проекте это не работает.

Кто-нибудь знает, для чего выполняется сбойная функция _Orphan_range?

Ответы [ 3 ]

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

Стирание из std :: vector делает недействительными итераторы. см. STL vector :: erase Поэтому it2 является недействительным после первого вызова стирания. Увы, проверка "(it2! = LIds.end ())" не будет верной.

измените свой код на:

if (*it2 == lSomeUuid) {
  it2 = lIds.erase(it2);
  break;
}  
0 голосов
/ 22 сентября 2011

Разве не ваш

 "theAs.find(lSomeUint32);"

возвращает позицию индекса, а не итератор Map ::? Я не уверен в этом. Вы можете проверить это? Функция find () возвращает позицию lSomeUint32 в As и возвращает позицию этого lSomeUint32 в строке (если она присутствует). Я полагаю, это причина, по которой ваша функция стирания выдает ошибку. Он не может удалить данные, которых нет или которые не входят в объем вашей программы.

Даже в противном случае, если ваш find () возвращает объект карты, я бы, в дополнение к этому, добавил бы простую структуру if, чтобы проверить, возвращает ли этот конкретный find () какой-либо объект или имеет значение NULL, просто чтобы убедиться, что итератору назначен значение до эксплуатации.

Просто предложение.

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

Вы сравниваете с неправильным end итератором.

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

Примечание lIds и pIds. Попробуйте использовать больше букв в именах переменных и не используйте венгерские обозначения. Вы поймали Ids_ptr почти мгновенно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...