2012-11-27 88 views
8

當我有塊被定義爲一個簡單的結構的unordered_map<Block, int>如下:SIGFPE訪問unordered_map

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 0.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>&

+0

與你的問題無關,但你不應該放置函數/類/等。在'std'命名空間中。 –

+0

在這裏可能的重複http://stackoverflow.com/questions/8286103/strange-unordered-map-situation –

+0

@Sergey我看到了一個,但解決方案似乎沒有任何關係我的問題 - 整個代碼實際上只在一個頭文件中(並且從我的角度來說是愚蠢的,不要在原始問題中注意到,mea culpa)。 – Voo

回答

5

另外:如果你的散列函數不能拋出,那麼給它一個noexcept異常規範是非常重要的,否則散列表需要將每個元素的散列碼存儲在元素本身旁邊(這會增加內存使用並影響性能),所以不能拋出的容器操作不必重新計算哈希碼。

的SIGFPE零意味着鴻溝,並從回溯它發生在這裏:

{ return __num % __den; } 

這可能意味着__den爲零。該值來自哈希映射的桶計數,該值不應爲零。

您能否確認當它崩潰m._M_bucket_count爲零?

如果是這樣,要麼則表明您已經以某種方式損壞的地圖(你試過用-D_GLIBCXX_DEBUG編譯到打開的libstdC++調試模式檢查?您是否嘗試過valgrind下運行?),或者有一個在的libstdC++代碼中的錯誤。

4

我有完全相同的問題。這是memset意外地應用於容器數據造成的。

2

在我的情況下,由於靜態init失敗發生同樣的問題。 從一個目標文件中,我調用了在第二個目標文件中定義的靜態std :: unordered_map的emplace方法。由於起始數據在BSS,桶計數值爲零=> SIGFPE。