访问unordered_map时为SIGFPE [英] SIGFPE when accessing unordered_map

查看:304
本文介绍了访问unordered_map时为SIGFPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 unordered_map< Block,int> ,其中Block是一个简单的结构,定义如下:

I have an unordered_map<Block, int> with Block being a simple struct defined as follows:

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和clang ++ 3.1相同):

When trying to access the map, I do get the following error message in gdb (same for both g++ 4.7.1 as well as clang++ 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中的版本)

My libstdc++ version is 3.4.17 (i.e. the version from 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

编辑:只要输入相同的参数,我并不认为它会真正改变 where 的功能。确实:

I didn't think it would actually make a difference where I call the function as long as I give it the same arguments, but apparently it does:

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

leads错误,而只具有:

leads to the error, while just having:

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

效果很好(存在一个简单的 vector< Block>&

works perfectly fine (blocks being a simple vector<Block>&)

推荐答案

另外:如果您的哈希函数无法抛出,那么给它一个 noexcept 异常规范非常重要,否则哈希表需要将每个元素的哈希码与元素本身一起存储(这样会增加内存使用量并影响性能),因此不必抛出的容器操作不必重新计算哈希码。

Aside: if your hash function cannot throw then it's quite important to give it a noexcept exception-specification, otherwise the hash table needs to store every element's hash code alongside the element itself (which increases memory usage and affects performance) so that container operations that must not throw do not have to recalculate the hash code.

SIGFPE表示除以零,从回溯开始,它发生在这里:

The SIGFPE implies a divide by zero and from the backtrace it happens here:

    { return __num % __den; }

这可能意味着 __ den 为零。该值来自哈希映射的存储区计数,该值不应为零。

which probably means __den is zero. That value comes from the hash map's bucket count, which should not be zero.

您可以确认崩溃时 m._M_bucket_count 为零吗?

Can you confirm that when it crashes m._M_bucket_count is zero?

如果是,则表明您以某种方式破坏了地图(是否尝试使用 -D_GLIBCXX_DEBUG 打开libstdc ++调试模式检查吗?您是否尝试在 valgrind 下运行?)或libstdc ++代码中有错误。

If so, that either indicates you've corrupted the map somehow (have you tried compiling with -D_GLIBCXX_DEBUG to turn on the libstdc++ Debug Mode checks? Have you tried running under valgrind?) or there's a bug in the libstdc++ code.

这篇关于访问unordered_map时为SIGFPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆