访问unordered_map时SIGFPE(SIGFPE when accessing unord

2019-08-03 05:52发布

我有一个unordered_map<Block, int>带座被定义如下一个简单的结构:

struct Block {
    size_t start;
    size_t end;

    bool operator==(const Block& b) const {
        return start == b.start && end == b.end;
    }
};

namespace std {
template<>
struct hash<Block> {
    size_t operator()(const Block& b) const {
        return b.start;
    }
};
} 

当试图访问地图,我得到在gdb以下错误消息(两者相同的g ++ 4.7.1以及铛++ 3.1):

Program received signal SIGFPE, Arithmetic exception.
0x0000000000401e0b in std::__detail::_Mod_range_hashing::operator() (this=0x7fffffffd8e0, __num=0, __den=0)
    at /usr/include/c++/4.7/bits/hashtable_policy.h:245
245     { return __num % __den; }

我的libstdc ++版本是3.4.17(即从GCC 4.7版)

相关回溯:

#0  0x0000000000401e0b in std::__detail::_Mod_range_hashing::operator() (this=0x7fffffffd8e0, __num=0, __den=0)
    at /usr/include/c++/4.7/bits/hashtable_policy.h:245
#1  0x0000000000407199 in std::__detail::_Hash_code_base<Block, std::pair<Block const, int>, std::_Select1st<std::pair<Block const, int> >, std::hash<Block>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>::_M_bucket_index (this=0x7fffffffd8e0, __c=0, __n=0) at /usr/include/c++/4.7/bits/hashtable_policy.h:787
#2  0x0000000000405230 in std::_Hashtable<Block, std::pair<Block const, int>, std::allocator<std::pair<Block const, int> >, std::_Select1st<std::pair<Block const, int> >, std::equal_to<Block>, std::hash<Block>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, true, false, true>::_M_bucket_index
    (this=0x7fffffffd8e0, __k=..., __c=0) at /usr/include/c++/4.7/bits/hashtable.h:466
#3  0x00000000004038de in std::__detail::_Map_base<Block, std::pair<Block const, int>, std::_Select1st<std::pair<Block const, int> >, true, std::_Hashtable<Block, std::pair<Block const, int>, std::allocator<std::pair<Block const, int> >, std::_Select1st<std::pair<Block const, int> >, std::equal_to<Block>, std::hash<Block>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, true, false, true> >::at (
    this=0x7fffffffd8e0, __k=...) at /usr/include/c++/4.7/bits/hashtable_policy.h:474
#4  0x0000000000403001 in SplicedAlignment::FindOptimalEndBlock() const::{lambda(Block const&)#1}::operator()(Block const&) const (__closure=0x7fffffffd990, block=...) at splicing.cpp:151
#5  0x00000000004040b3 in std::for_each<__gnu_cxx::__normal_iterator<Block const*, std::vector<Block, std::allocator<Block> > >, SplicedAlignment::FindOptimalEndBlock() const::{lambda(Block const&)#1}>(__gnu_cxx::__normal_iterator<Block const*, std::vector<Block, std::allocator<Block> > >, SplicedAlignment::FindOptimalEndBlock() const::{lambda(Block const&)#1}, SplicedAlignment::FindOptimalEndBlock() const::{lambda(Block const&)#1}) (__first=..., __last=..., __f=...)
    at /usr/include/c++/4.7/bits/stl_algo.h:4442

编辑:我没想到它居然会有所作为,只要我给它相同的参数我打电话的功能,但显然它的作用:

std::for_each(blocks.begin(), blocks.end(), [&](const Block& block) {
    map.at(block);
}

导致错误,而只是有:

const Block& block = blocks[0];
map.at(block);

工作完全正常( blocks是一个简单的vector<Block>&

Answer 1:

旁白:如果你的哈希函数不能再扔这是很重要的,给它一个noexcept异常规范,否则,哈希表需要存储每个元素的散列码元素本身一起(这增加了内存使用情况和对性能的影响),因此集装箱业务是不能抛出不必重新计算哈希码。

该SIGFPE零意味着鸿沟,并从回溯它发生在这里:

    { return __num % __den; }

这可能意味着__den为零。 该值来自散列图的桶数,这不应该是零。

你能否证实,当它崩溃m._M_bucket_count是零?

如果是这样,要么则表明您已经以某种方式损坏的地图(你试过用编译-D_GLIBCXX_DEBUG接通的libstdc ++调试模式检查?您是否尝试过下运行valgrind ?),或者有一个在的libstdc ++代码中的错误。



Answer 2:

我有完全相同的问题。 它是由偶然的memset施加到容器的数据而引起的。



Answer 3:

在我的情况下发生了同样的问题,因为静态初始化惨败。 从一个对象的文件I呼吁静态的std :: unordered_map将其在第二目标文件中定义布设方法。 由于在开始数据是在BSS中,桶计数值为零=> SIGFPE。



文章来源: SIGFPE when accessing unordered_map