2017-01-28 10 views
-3

(Ошибка сегментации) Ошибка при доступе к значению, связанному с ключом на неупорядоченной карте. Любые указатели, где я делаю ошибку?Ошибка Seg в unordered_map <int, std :: vector <double>>

вина Сегментация в следующем фрагменте кода:

void read_mdl(const std::string& fname) { 
     std::ifstream f(fname); 

     std::unordered_map<int, std::vector<double>> pt_; 

     while(f) { 
      int xi = -1; 
      int pa = 0; 
      double score = -1; 
      f >> xi >> pa >> score; 
      if(xi == -1) { break; } 

      std::unordered_map<int, std::vector<double>>::iterator it = pt_.find(pa); 

      std::cout << xi << " " << pa << " " << score << std::endl; 

      if (it != pt_.end()) { 
       // Update from @Matthias247 
       auto a = pt_.insert(std::make_pair(pa, std::vector<double>(n_, 0))); 
       it = a.first; 
      } 

      (it->second)[xi] = score; // causing segmentation fault 
     } 
    } 
+3

Подумайте о том, что произойдет, когда '' == Оно деталь A. 'pt_.end()'. – songyuanyao

+1

Недостаток вашего способа проверки отсутствия данных из потока. См. [этот старый мой ответ] (http://stackoverflow.com/a/13379073/440558), почему. Также читайте [«Почему iostream :: eof внутри условия цикла считается неправильным?»] (Http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) , Использовать, например. 'while (f >> xi >> pa >> score)' вместо этого. –

+0

Также рассмотрите, что произойдет, если 'xi> = n_'. –

ответ

0

Ваш итератора нарушается в случае, когда он не находит элемент. Вы вставляете новый элемент в этом случае с pt_.insert, но не меняете итератор. После этого доступ к нему приводит к segfault. Либо выполните поиск или поиск, если insert возвращает итератор и назначает его it.

Update:

Если я понимаю insert API правильно, он должен работать как

if (it != pt_.end()) { 
    auto a = pt_.insert(std::make_pair(pa, std::vector<double>(n_, 0))); 
    it = a.first; 
} 

(it->second)[xi] = score; 
+0

Ошибка все еще сохраняется – letsBeePolite

+1

Это была, тем не менее, одна из причин, по которой она разбилась. – Matthias247

0

Нашли ошибку.

Это была неправильная проверка того, существует или нет ключ.

Что касается моего сниппета:

if (it != pt_.end()) // incorrect way 

if (it == pt_.end()) // right way