繁体   English   中英

具有std无序映射的SIGFPE

[英]SIGFPE with std unordered map

下面是一个简单的应用程序,如果我在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://stackoverflow.com/a/36406774/3884862中有一个与此问题相关的指针,但我不知道为什么会这样。

我用它编译

g ++ -std = c ++ 14 main.cc table_provider.cc -o测试

g ++(Ubuntu 5.4.0-6ubuntu1〜16.04.11)5.4.0 20160609

您有一个静态初始化顺序fiasco

不要将定义放在文件中,因为这将导致每个翻译单元在头文件中定义的变量都有自己的副本。

这意味着getConfigTable返回的gTable1将不同于main.cc文件中定义的gTable1 并且其他gTable1在使用时可能尚未初始化。

解决方案是将全局变量放在单个转换单元(源文件)中。 或者更好的是,根本没有全局变量。

此代码遭受静态初始化顺序fiasco的困扰。 gTable1table_provider.cc转变单元可以当你被初始化没有初始化gNamemain.cc翻译单元。 请注意,由于gTable1是在头文件中声明的static变量,因此每个转换单元将具有一个单独的实例。 因此,直接访问它并使用getConfigTable将引用不同的对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM