将元素添加到 std::map 时出现隔离错误
Segfault when adding an element to a std::map
当我尝试在地图中插入一个元素时,发生了一些奇怪的事情
主.cpp
S3Wrapper wrapper = S3Wrapper::getS3Wrapper();
int main(){
return 0;
}
所以基本上只有单例被称为 S3Wrapper
S3Wrapper.hpp
class S3Wrapper
{
S3Wrapper(std::string bucketName);
public:
~S3Wrapper();
static S3Wrapper &getS3Wrapper(std::string name = BUCKET_NAME);
}
和 S3Wrapper.cpp
static std::map<std::string, S3Wrapper*> _wrapperMap;
S3Wrapper& S3Wrapper::getS3Wrapper(std::string name)
{
auto it = _wrapperMap.find(name);
if (it == _wrapperMap.end())
{
auto t = new S3Wrapper(name);
_wrapperMap[name] = t;
return *(_wrapperMap[name]);
}
return *(it->second);
}
当我编译时,我没有任何错误/警告,但随后程序出现段错误:
g++ main.cpp S3Wrapper.cpp -std=c++0x -ls3 -g3
GDB 的结果
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7937c4a in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) bt
#0 0x00007ffff7937c4a in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1 0x0000000000406295 in std::_Rb_tree_iterator<std::pair<std::string const, S3Wrapper*> >::operator-- (this=0x7fffffffd8b0) at /usr/include/c++/4.8/bits/stl_tree.h:204
#2 0x00000000004061f7 in std::_Rb_tree<std::string, std::pair<std::string const, S3Wrapper*>, std::_Select1st<std::pair<std::string const, S3Wrapper*> >, std::less<std::string>, std::allocator<std::pair<std::string const, S3Wrapper*> > >::_M_get_insert_unique_pos (this=0x60b580 <_wrapperMap>, __k=...) at /usr/include/c++/4.8/bits/stl_tree.h:1333
#3 0x00000000004058f5 in std::_Rb_tree<std::string, std::pair<std::string const, S3Wrapper*>, std::_Select1st<std::pair<std::string const, S3Wrapper*> >, std::less<std::string>, std::allocator<std::pair<std::string const, S3Wrapper*> > >::_M_get_insert_hint_unique_pos (this=0x60b580 <_wrapperMap>, __position=..., __k=...) at /usr/include/c++/4.8/bits/stl_tree.h:1425
#4 0x000000000040511c in std::_Rb_tree<std::string, std::pair<std::string const, S3Wrapper*>, std::_Select1st<std::pair<std::string const, S3Wrapper*> >, std::less<std::string>, std::allocator<std::pair<std::string const, S3Wrapper*> > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<std::string const&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<std::string const, S3Wrapper*> >, std::piecewise_construct_t const&, std::tuple<std::string const&>&&, std::tuple<>&&) (this=0x60b580 <_wrapperMap>, __pos=...) at /usr/include/c++/4.8/bits/stl_tree.h:1673
#5 0x0000000000404d24 in std::map<std::string, S3Wrapper*, std::less<std::string>, std::allocator<std::pair<std::string const, S3Wrapper*> > >::operator[] (this=0x60b580 <_wrapperMap>, __k=...)
at /usr/include/c++/4.8/bits/stl_map.h:465
#6 0x0000000000404945 in S3Wrapper::getS3Wrapper (name=...) at S3Wrapper.cpp:55
#7 0x00000000004021e3 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at main.cpp:8
#8 0x00000000004022ce in _GLOBAL__sub_I_wrapper () at main.cpp:41
#9 0x0000000000406b7d in __libc_csu_init ()
#10 0x00007ffff7308e55 in __libc_start_main (main=0x401edc <main()>, argc=1, argv=0x7fffffffdc28, init=0x406b30 <__libc_csu_init>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffdc18) at libc-start.c:246
#11 0x0000000000401b79 in _start ()
55行:_wrapperMap[name] = t;
如果我在向量中插入t,我没有任何问题
这是
静态初始化的惨败:在不同翻译单元中定义的静态变量以未指定的顺序初始化,因此不能保证_wrapperMap
在初始化需要之前wrapper
初始化。
最好的解决方案是避免静态/全局变量。它们通常只会造成麻烦。
如果你真的想要全局状态,一个更安全的选择是使用局部静态变量:
std::map<std::string, S3Wrapper*> & wrapperMap() {
static std::map<std::string, S3Wrapper*> map;
return map;
}
这保证在第一次调用函数时初始化,因此在初始化之前没有使用映射的危险。在程序结束时销毁静态变量时,您可能仍然会遇到问题。
请注意,_wrapperMap
是保留的(在全局命名空间中),因此应选择一个不带前导下划线的名称,或将其放在命名空间中。
非常感谢
迈克的解释,这对我有很大帮助。
在我的情况下,我无法轻松摆脱静态初始化:所以我只是更改了 Makefile 中链接的对象文件的顺序,这解决了我的问题!不确定链接器的顺序是否是我们可以依赖的(我正在使用 GCC)
相关文章:
- 从矢量中删除元素后出现隔离错误
- 在 gtest 中初始化堆栈上的引用变量的隔离错误
- 线程时访问静态映射时出现隔离错误
- 并行快速排序分区中的隔离错误
- C++多线程程序:变量定义为类成员的隔离错误
- TFLite 隔离错误,通过获取C++输入和输出
- 我只是在寻找模板,在我的书中找到了这段代码,这显示了隔离错误?
- pthread_create中错误 4 的隔离错误
- 递归树遍历/分支删除的隔离错误
- 在类模板上使用 arm gcc 编译期间的隔离错误
- 从大量文件读取时出现隔离错误
- 在PHP扩展中使用emalloc从线程时出现隔离错误
- 通过 Boost Python 在C++对象之间传递共享指针的隔离错误
- 在QT中单击菜单时出现隔离错误
- 尝试访问标头声明成员时出现隔离错误
- 搜索链表时出现隔离错误
- 模板化子类析构函数中的隔离错误
- 插件中节点.js/Nan 回调C++不频繁的隔离错误
- 将行添加到 GTKTreeView 时的隔离错误
- 找不到命令时打开的隔离错误