stl — C ++ std :: unordered_set SIGFPE исключение

Я написал программу, и меня очень удивил тот факт, что я запускал ее десятки раз — я даже записывал результаты нескольких выполнений — и теперь она не работает.

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

Проблема заключается в SIGFPE, который возникает в разных выполнениях программы, в зависимости от ввода. Бывает, хотя сигнал повышается во время вставив значение в std::unordered_set<Point<T> *>.

Вот фрагмент кода, где я делаю такую ​​вставку:

std::vector<Point<T> *> _point, _centroid;
std::vector<std::unordered_set<Point<T> *> > _cluster;

// Main procedure -- pseudocode
for (point in _point) {
cluster_id = centroid_with_min_distance(point, _centroid);
has_changed = _change_cluster(point, cluster_id);
}

// Changes from one "point->_cluster's unordered_set" to "c's unordered_set"bool _change_cluster(Point<T> *point, const unsigned int& c) {

if ((point->_cluster == c) &&
(_cluster[c].find(point) != _cluster[c].end())) {
return false;
}

_cluster[point->_cluster].erase(point);
_cluster[c].insert(point); // Insertion that raises the SIGFPE exception
point->_cluster = c;
return true;

}

Вот важный раздел вывода Вальгринда:

==17636== Invalid read of size 8
==17636==    at 0x40A758: std::pair<std::__detail::_Hashtable_iterator<
Point<unsigned int>*, true, false>, bool>
std::_Hashtable<Point<unsigned int>*, Point<unsigned int>*,
std::allocator<Point<unsigned int>*>,
std::_Identity<Point<unsigned int>*>,
std::equal_to<Point<unsigned int>*>,
std::hash<Point<unsigned int>*>,
std::__detail::_Mod_range_hashing,
std::__detail::_Default_ranged_hash,
std::__detail::_Prime_rehash_policy, false, true, true>::
_M_insert<Point<unsigned int>* const&>(
Point<unsigned int>* const&&&,
std::integral_constant<bool, true>) (hashtable.h:966)
==17636==    by 0x408EDA: std::_Hashtable<Point<unsigned int>*,
Point<unsigned int>*, std::allocator<Point<unsigned int>*>,
std::_Identity<Point<unsigned int>*>,
std::equal_to<Point<unsigned int>*>,
std::hash<Point<unsigned int>*>,
std::__detail::_Mod_range_hashing,
std::__detail::_Default_ranged_hash,
std::__detail::_Prime_rehash_policy, false, true, true>::
insert(Point<unsigned int>* const&) (hashtable.h:400)
==17636==  ... (calls from my program) ...
==17636==  Address 0x620a028 is not stack'd, malloc'd or (recently) free'd
==17636==
==17636==
==17636== Process terminating with default action of signal 8 (SIGFPE)
==17636==  Integer divide by zero at address 0x402D07D7C
==17636==    at 0x40252F: std::__detail::_Mod_range_hashing::operator()(
unsigned long, unsigned long) const (hashtable_policy.h:376)
==17636==    by 0x40A66C: std::__detail::_Hash_code_base<Point<unsigned int>*,
Point<unsigned int>*, std::_Identity<Point<unsigned int>*>,
std::equal_to<Point<unsigned int>*>,
std::hash<Point<unsigned int>*>,
std::__detail::_Mod_range_hashing,
std::__detail::_Default_ranged_hash, false>::_M_bucket_index(
Point<unsigned int>* const&, unsigned long,
unsigned long) const (hashtable_policy.h:758)
==17636==    by 0x40A772: std::pair<std::__detail::_Hashtable_iterator<
Point<unsigned int>*, true, false>, bool>
std::_Hashtable<Point<unsigned int>*, Point<unsigned int>*,
std::allocator<Point<unsigned int>*>,
std::_Identity<Point<unsigned int>*>,
std::equal_to<Point<unsigned int>*>,
std::hash<Point<unsigned int>*>,
std::__detail::_Mod_range_hashing,
std::__detail::_Default_ranged_hash,
std::__detail::_Prime_rehash_policy, false, true, true>::
_M_insert<Point<unsigned int>* const&>(
Point<unsigned int>* const&&&,
std::integral_constant<bool, true>) (hashtable.h:966)
==17636==    by 0x408EDA: std::_Hashtable<Point<unsigned int>*,
Point<unsigned int>*, std::allocator<Point<unsigned int>*>,
std::_Identity<Point<unsigned int>*>,
std::equal_to<Point<unsigned int>*>,
std::hash<Point<unsigned int>*>,
std::__detail::_Mod_range_hashing,
std::__detail::_Default_ranged_hash,
std::__detail::_Prime_rehash_policy, false, true, true>::
insert(Point<unsigned int>* const&) (hashtable.h:400)
==17636==    ... (calls from my program) ...

Вопрос здесь следующий: поскольку в моей программе есть расчеты, которые могут привести к делению на ноль — они, однако, не имеют прямого отношения к этому процессу — возможно, что ошибка затеняется вставкой? Или я должен сделать некоторую дополнительную обработку, вставляя указатели в std::unordered_set<T>?

Я собираю программу под x86_64 GNU/Linuxи я использую g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3,

3

Решение

Я подозреваю, что «с» находится вне диапазона _cluster, Можете ли вы заменить все _cluster[c] с _cluster.at(c)и посмотреть, найдет ли он ошибку вне диапазона.

Вывод valgrind указывает, что это недопустимое чтение, за которым следует ошибка целочисленного модуля. Так как это делает hash_code % bucket_countЯ подозреваю, что вы получили доступ за пределы вектора.

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

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]