在Jetson平台上编写Deepstream插件时遇到std::map容器导致的Segmentation fault问题。通过调试发现,当GObject的数据成员为std::map时,需要在GObject的构造函数中显式初始化std::map。
摘要生成于
,由 DeepSeek-R1 满血版支持,
去年和今年在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()函数来促使其实例化。
std
:
:
map
<string, uint32_t>
:
:
iterator it;
for
(
it= test.begin
()
; it!= test.end
()
; ++it
)
{
if
(
strcmp
(
“happy”,
(
it->first
)
.c_str
()
)
== 0
)
{
test.erase
(
it
)
;
报错😱😱😱:
代码与报错
在我的映像里,
C++
11的
emplace
函数的主要作用是减少一次类的构造函数
调用
。即在
insert
函数中构造函数可能被
调用
两次(一次指定的构造函数和一次复制构造函数),在
emplace
函数中应当不会用到复制构造函数。但是今天遇到了一个问题,代码如下
#include <iostream>
#include <cstring>
#include <strin...
emplace
emplace
操作是从
C++
11开始引入新特性,
emplace
操作是直接通过参数构造元素而不是拷贝元素到容器中这样可以减少拷贝从而提高性能。对于
map
是没有
emplace
_front、
emplace
_after、
emplace
_back这些操作的。
std
:
:
map
<Key,T,Compare,Allocator>
:
:
emplace
template<class...Args>
std
:
:
pair<iterator,bool>empl...
//m_oFunction
Map
[strKey] = pNew;
m_oFunction
Map
.
insert
(
std
:
:
map
<
std
:
:
string, MemoryRecord*>
:
:
value_type
(
strKey, pNew
)
)
;
第一句有时会导致崩溃.
第二句则正常.
无序
map
容器,unordered_
map
容器不会像
map
容器那样对存储的数据进行排序。
unordered_
map
容器底层采用的是哈希表存储结构,该结构本身不具有对数据的排序功能,所以此容器内部不会自行对存储的键值对进行排序。
关联容器删除一个元素的时候,当前的迭代器会失效,其他的迭代器不会失效,增加一个元素的时候,迭代器不会失效。
线程安全性的保证:
#0 0x00000000008da74a in
std
:
:
local_Rb_tree_decrement
(
std
:
:
_Rb_tree_node_base*
)
()
Missing separate debuginfos, use
:
debuginfo...
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~de
fault
-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~de
fault
-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width
:
50%"]
[ .reference_list ]