调用std::map的emplace()出现Segmentation fault (core dumped)

10 篇文章 4 订阅
6 篇文章 1 订阅

去年和今年在Jetson板子上写Deepstream插件代码时使用到std::map容器时都遇到过奇怪的崩溃,这些崩溃和网上别人说的引用的值没有初始化导致的崩溃根本不是一回事,就是一个非常简单的定义:

std::map<std::string, int>或者std::map<int, int>

这里的key和value根本没什么复杂的类型,所以根本不是别人常说的那种情况。

代码很简单:

在插件的GObject里定义了一个全局性的 std::map<std::string, int> source_names; 然后在set_property()里访问它:

source_names.emplace(name,id);

name和id的数据都是合法的,但就是崩溃在这里:

Segmentation fault (core dumped)

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
Core was generated by `./bright'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000007f8db03ce8 in ?? () from /usr/lib/aarch64-linux-gnu/libstdc++.so.6
[Current thread is 1 (Thread 0x7f77519010 (LWP 16368))]
(gdb) bt
#0  0x0000007f8db03ce8 in  () at /usr/lib/aarch64-linux-gnu/libstdc++.so.6
#1  0x0000007f8e4972c0 in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_M_get_insert_unique_pos(int const&) () at /usr/lib/aarch64-linux-gnu/libncnn.so.1
#2  0x0000007f62667718 in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_M_emplace_unique<int, int&>(int&&, int&) (this=0x5571de7418) at /usr/include/c++/7/bits/stl_tree.h:2356
#3  0x0000007f62663f48 in std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::emplace<int, int&>(int&&, int&) (this=0x5571de7418)
    at /usr/include/c++/7/bits/stl_map.h:569
#4  0x0000007f6265e4a4 in gst_dspeoplecounter_set_property(GObject*, guint, GValue const*, GParamSpec*) (object=0x5571de70d0, prop_id=2, value=0x7ff49cfb00, pspec=0x5571ee5270)
    at dspeoplecounter.cpp:273
#5  0x0000007f8f4b608c in g_object_set_valist () at /usr/lib/aarch64-linux-gnu/libgobject-2.0.so.0
#6  0x0000007f8f4b6ad0 in g_object_set () at /usr/lib/aarch64-linux-gnu/libgobject-2.0.so.0
#7  0x0000005570f52608 in br_main(int, char**) ()
#8  0x0000005570e5f7f4 in main ()

无论改成旧式的[]还是insert()插值(去年的Segmentation fault是用[]访问map就崩溃,改成用insert()就不会,也是让人非常的惊讶!),都一样会发生Segmentation fault, 大为惊讶,按理std::map定义就可以使用啊,根本无需什么初始化。为了搞清楚原因到网上浏览了一番,看到stackflow上别人也遇到过同样的问题,居然也是用先调用clear()这个办法绕过去!Google的人遇到了类似的崩溃std::map gives errors · Issue #542 · google/sanitizers · GitHub不过看文章分析他们的问题应该是由于他们自己的程序把内存搞乱了。

经过几轮实验,这个问题弄清楚了,当GObject的数据成员是std::map时,map类型变量定义时不会像通常的程序中那样自动实例化的,需要在GObject的 *_init()函数里对这样的数据成员变量显式创建实例,或者调用std::map的clear()函数来促使其实例化。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
std::map.emplace是一个用于向std::map容器中插入元素的函数。它的作用是在map中插入一个键值对,并返回一个指向插入的元素的迭代器。emplace函数的参数可以是一个或多个键和值,它会使用这些参数直接构造一个新的键值对并插入到map中。如果插入成功,emplace函数会返回一个指向插入元素的迭代器,否则返回一个指向已存在的相同键的元素的迭代器。这种方式比使用insert函数更高效,因为emplace函数会避免额外的拷贝构造。 例如,可以使用emplace函数向一个std::map<std::string, std::string>对象中插入元素: std::map<std::string, std::string> m; m.emplace(std::make_pair("key", "value")); 这样就向map中插入了一个键值对,键为"key",值为"value"。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【C++】17. map []操作符、insert()、emplace()](https://blog.csdn.net/u011754972/article/details/116798048)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [std::map emplace示例](https://blog.csdn.net/qq_34999565/article/details/119908509)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arnold-FY-Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值