3

私はプログラムを作成しましたが、それを何十回も実行したという事実に非常に面白がっています。複数の実行の結果を書き留めたことがありますが、現在は機能しません。

私は凧として高いと思うかもしれませんし、単にいくつかの行を変更したかもしれないと思うかもしれませんが、プログラムで変更を加えたことを本当に覚えていません。

問題は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;

}

valgrindの出力の重要なセクションは次のとおりです。

==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います。

4

1 に答える 1

5

'c'はの範囲外だと思い_clusterます。_cluster[c]すべてをに置き換え_cluster.at(c)て、範囲外のエラーが検出されるかどうかを確認できますか。

valgrindの出力は、無効な読み取りとそれに続く整数モジュラスエラーであることを示しています。やっているのでhash_code % bucket_count、ベクターの範囲外にアクセスしたのではないかと思います。

余談です_が、グローバル名前空間にあるかのように、最初から名前を付けるのは危険な場合があります。技術的には実装用に予約されています。

于 2013-02-01T22:21:42.527 に答える