带有 std unordered_map 的 SIGFPE
Posted
技术标签:
【中文标题】带有 std unordered_map 的 SIGFPE【英文标题】:SIGFPE with std unordered map 【发布时间】:2019-01-15 09:14:32 【问题描述】:下面是一个简单的应用程序,如果我取消注释 main.cc 中提到的行,它会为我导致 SIGFPE。
config.h
#ifndef SRC_CONFIG_H_
#define SRC_CONFIG_H_
#include <cstdint>
#include <unordered_map>
#include <string>
#include <tuple>
#include <vector>
using ConfigTable_t = std::unordered_map<uint16_t, std::tuple<std::string, std::vector<uint8_t> > >;
static const ConfigTable_t gTable1
0x100, std::make_tuple( "table1", std::vector<uint8_t> 5,5,5,5,5,5 )
;
static const ConfigTable_t gTable2
0x200, std::make_tuple( "table2", std::vector<uint8_t> 0,1,2,3,4,5 )
;
const ConfigTable_t & getConfigTable();
#endif
table_provider.cc
#include "config.h"
const ConfigTable_t & getConfigTable()
return gTable1;
main.cc
#include "config.h"
static const uint16_t gId = 0x100;
// static const std::string gName = std::get<0>(getConfigTable().at(gId)); // <-- Doesn't work
static const std::string gName = std::get<0>(gTable1.at(gId)); // <-- Works
int main()
return 0;
https://***.com/a/36406774/3884862 中有一个与此问题相关的指针,但我无法弄清楚它为什么会发生。
我用
编译g++ -std=c++14 main.cc table_provider.cc -o test
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
【问题讨论】:
【参考方案1】:你有一个static initialization order fiasco。
不要将定义放在 header 文件中,因为这会导致每个 translation unit 将拥有自己的头文件中定义的变量的副本。
这意味着getConfigTable
返回的gTable1
将不同于main.cc
文件中定义的gTable1
。而其他gTable1
在你使用的时候可能还没有初始化。
解决方案是将全局变量放在一个单个翻译单元(源文件)中。或者更好的是,根本没有全局变量。
【讨论】:
【参考方案2】:此代码受到static initialization order fiasco 的影响。当您在 main.cc
翻译单元中初始化 gName
时,table_provider.cc
翻译单元中的 gTable1
可能未初始化。请注意,由于gTable1
是在头文件中声明的static
变量,因此每个翻译单元都有一个单独的实例。所以直接访问它并使用getConfigTable
将引用不同的对象。
【讨论】:
以上是关于带有 std unordered_map 的 SIGFPE的主要内容,如果未能解决你的问题,请参考以下文章
如何在带有来自 std::string 的 unordered_map 的字符串文字上使用 is_transparent 功能?
Qt - std::unordered_map - 销毁时间
std::unordered_map::clear() 做啥?