STL中map的[]运算导致程序挂掉的问题

2023-05-16

在项目的开发中,使用[]设置map变量时,出现了Segment Fault的问题,使用GDB bt命令得到调用栈(中间部分被我去掉了)如下:

#0  0x00000000008da74a in std::local_Rb_tree_decrement(std::_Rb_tree_node_base*) ()
Missing separate debuginfos, use: debuginfo-install cyrus-sasl-lib-2.1.26-20.el7_2.x86_64 glibc-2.17-196.el7_4.2.x86_64 gperftools-libs-2.4-8.el7.x86_64 keyutils-libs-1.5.8-3.el7.x86_64 krb5-libs-1.15.1-8.el7.x86_64 libcom_err-1.42.9-10.el7.x86_64 libcurl-7.29.0-42.el7_4.1.x86_64 libgcc-4.8.5-16.el7_4.2.x86_64 libidn-1.28-4.el7.x86_64 libselinux-2.5-11.el7.x86_64 libssh2-1.4.3-10.el7_2.1.x86_64 libstdc++-4.8.5-16.el7_4.2.x86_64 libunwind-1.1-5.el7_2.2.x86_64 mariadb-libs-5.5.56-2.el7.x86_64 nspr-4.13.1-1.0.el7_3.x86_64 nss-3.28.4-15.el7_4.x86_64 nss-softokn-freebl-3.28.3-8.el7_4.x86_64 nss-util-3.28.4-3.el7.x86_64 openldap-2.4.40-13.el7.x86_64 openssl-libs-1.0.2k-8.el7.x86_64 pcre-8.32-17.el7.x86_64 zlib-1.2.7-17.el7.x86_64
(gdb) bt
#0  0x00000000008da74a in std::local_Rb_tree_decrement(std::_Rb_tree_node_base*) ()
#1  0x0000000000823083 in operator-- (this=<synthetic pointer>) at /usr/include/c++/4.8.2/bits/stl_tree.h:204
#2  std::_Rb_tree<unsigned int, std::pair<unsigned int const, std::map<unsigned int, int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, int> > > >, std::_Select1st<std::pair<unsigned int const, std::map<unsigned int, int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, int> > > > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, std::map<unsigned int, int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, int> > > > > >::_M_get_insert_unique_pos
    (this=this@entry=0x7fe6cdb45a9c, __k=@0x3a82300: 3) at /usr/include/c++/4.8.2/bits/stl_tree.h:1333
#3  0x000000000082315b in std::_Rb_tree<unsigned int, std::pair<unsigned int const, std::map<unsigned int, int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, int> > > >, std::_Select1st<std::pair<unsigned int const, std::map<unsigned int, int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, int> > > > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, std::map<unsigned int, int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, int> > > > > >::_M_get_insert_hint_unique_pos (this=this@entry=0x7fe6cdb45a9c, __position=..., __position@entry=..., __k=@0x3a82300: 3) at /usr/include/c++/4.8.2/bits/stl_tree.h:1441
#4  0x00000000008212f1 in _M_emplace_hint_unique<const std::piecewise_construct_t&, std::tuple<unsigned int const&>, std::tuple<> > (__pos=..., this=0x7fe6cdb45a9c) at /usr/include/c++/4.8.2/bits/stl_tree.h:1673
#5  operator[] (__k=<synthetic pointer>, this=0x7fe6cdb45a9c) at /usr/include/c++/4.8.2/bits/stl_map.h:465
...
...
...
#13 0x000000000047f380 in ApplicationBase::Run (this=0xf789e0 <Singleton<Application>::get_instance()::t>) at commlib/application_base.cpp:176
#14 0x00007fe6e15abc05 in __libc_start_main () from /lib64/libc.so.6
#15 0x0000000000443707 in _start ()

一开始遇到这个问题是懵逼的,因为觉得自己的做法是没问题的,虽然用的是map中嵌套了map:

std::map<uint32_t, std::map<uint32_t,  int32_t> > group_chess_;

但看了下项目其他地方也有用到map嵌套map的,也是通过两个[]进行赋值,并没有出现Segment Fault的情况。通过网上搜索了下,找到下面两个链接:

static的map成员的初始化顺序居然和编译器相关

全局变量相互依赖和初始化顺序的解决办法

然后发现自己在赋值之前,还通过group_chess_.find(id)操作对其进行操作,猜测可能是自己先find操作,导致对group_chess_的一些重要内容没有进行初始化,从而赋值出错。便在类的构造函数里面执行了这项操作:group_chess_.clear()。结果问题就解决了。

看来的确是因为提前find操作导致部分内容没有被初始化,接下来想看看侯捷的《STL源码剖析》了解下为什么,希望能找到答案,也是深入了解下STL。

-------------------------------------------------------------------------------------------------------------------------------------------------

2019.4.17更新

跟随调用栈看了下STL的源码,发现find并没有做特殊的操作,并且[]操作也是有申请空间的。

搜索答案时找到也有小哥遇到同样问题,并且也是同样的clear就可以了,链接如下:

Why would an empty std::map seg fault on the first insert?

Oops

自己简单写了代码测试下:

#include <map>

class Test{
    private:
        int ii; 
        std::map<int, std::map<int, int> > inner;
    public:
        Test() { 
            ii = 0;  
        }   
        void Set(int i) { 
            if (inner.find(i) == inner.end()) {
                inner[i][i] = i;  
            }   
        }   
};

int main() {
    Test test;
    test.Set(1);
    test.Set(2);
    test.Set(3);
    return 0;
}

测试中并没有出现Segment Fault,定位过程中看到下面这篇文章:

#pragma pack引起 stl的map/list在insert时报错:(Suspended : Signal : SIGSEGV:Segmentation fault)

虽然在项目其他头文件中有用到#pragma pack,但是都是成对的,并且出问题的类中头文件没有用到这个。所以应该不是这个问题导致的。目前怀疑是编译的时候某些选项导致的吧,接下来看下能怎么定位了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STL中map的[]运算导致程序挂掉的问题 的相关文章

  • std::stack 是否公开迭代器?

    是否std stack在 C STL 中公开底层容器的任何迭代器 还是应该直接使用该容器 根据堆栈的定义 堆栈没有迭代器 如果您需要带有迭代器的堆栈 则需要自己在其他容器 std list std vector 等 之上实现它 堆栈文档在这
  • std::find 的优点

    使用 C 11 有什么优势吗std find超过一个容器的find method 如果是std vector 其中没有find方法 确实std find使用一些智能算法或简单地迭代每个元素的天真的方法 如果是std map看来你需要传递一个
  • 为什么标准没有提供擦除删除惯用语的便利帮助程序?

    从 STL 中的集合中删除项目需要一种经常使用的技术 该技术已成为一种习惯用法 擦除 删除 惯用语 https en wikipedia org wiki Erase E2 80 93remove idiom 这个习语最常见的用法之一是删除
  • 在带有或不带有命名空间的 中使用类型

    在 C 11 中 我可以选择是否要使用带或不带命名空间 std 中定义的类型 至少我的编译器 g 4 7 接受这两种变体 我的问题是 使用 cstdint 中的 typedef 的推荐方法是什么 有或没有命名空间 有什么优点或缺点 或者这只
  • 使用连续内存并具有保留功能的映射和集合

    我使用了几张地图和套件 缺乏连续内存以及大量的分配 解除 是性能瓶颈 我需要一个主要与 STL 兼容的映射和集合类 它可以将连续的内存块用于内部对象 或多个块 它还需要有一个reserve函数 以便我可以预先分配预期的大小 在我自己编写之前
  • 对向量进行排序而不改变原始向量的最佳方法是什么?

    正如标题所说 我正在寻找一种在不修改原始向量的情况下对向量进行排序的方法 我的第一个想法当然是在排序之前创建向量的副本 例如 std vector
  • 哪个STL容器?

    我需要一个容器 不一定是 STL 容器 它可以让我轻松执行以下操作 在任意位置插入和移除元素 通过索引访问元素 以任意顺序迭代元素 I used 标准 列表 但它不会让我在任何位置插入 确实如此 但为此我必须迭代所有元素 然后在我想要的位置
  • 从 std::heap 中间删除一个元素

    我使用优先级队列作为调度程序 但有一个额外的要求 我需要能够取消预定的项目 这相当于从优先级队列中间删除一个项目 我不能使用std priority queue因为对除顶部之外的任何元素的访问都受到保护 我正在尝试使用algorithm的堆
  • 从函数返回 STL 向量 - 复制成本

    当您从函数返回 stl 向量时 vector
  • STL:为向量编写“where”运算符

    我需要根据几个布尔谓词找到向量中的索引 ex vector
  • 查找向量中最近的点

    给定一个具有多个值的排序向量 如下例所示 std vector
  • C++ 中有标准的日期/时间类吗?

    C stl 有标准时间类吗 或者我是否必须在写入流之前转换为 c 字符串 例如 我想将当前日期 时间输出到字符串流 time t tm ostringstream sout sout lt lt tm lt lt ends 在本例中 我将当
  • 用于列表和映射的 C++ 容器

    我们有一个键和值对的集合 我们需要一个容器 它可以帮助我们检索值 o 1 但也可以记住插入顺序 以便当我们进行迭代时 我们可以像插入顺序一样进行迭代 由于键是一个字符串 我们将无法使用集合或类似的结构 目前我们已经定义了自己的集合类 其中包
  • std::function 和 std::bind 行为

    我有这个代码 include
  • 使用 istream_iterator 范围构造时无法访问向量

    我尝试编译此代码片段 但出现编译器错误 使用 Visual Studio 2010 进行编译 include
  • 执行 set_difference 时出错:变量结果不是结构

    我在函数外部全局声明了一个设置变量 std set
  • 如何对多重映射中的键和值进行排序?

    建议使用任何方法对多重映射的键及其值进行排序 例如 输入 5 1 1 9 1 1 5 2 1 2 输出必须是 1 1 1 2 1 9 5 1 5 2 答案是emplace hint 伪代码如下所示 insert with hint M mm
  • Windows Unicode C++ 流输出失败

    我目前正在编写一个应用程序 它要求我在任意窗口上调用 GetWindowText 并将该数据存储到文件中以供以后处理 长话短说 我注意到我的工具在 战地 3 上失败了 我将问题范围缩小到窗口标题中的以下字符 http www filefor
  • STL迭代器是否保证集合更改后的有效性?

    假设我有某种集合 并且我在它的开头获得了一个迭代器 现在假设我修改了该集合 无论集合或迭代器的类型如何 我仍然可以安全地使用迭代器吗 为了避免混淆 以下是我讨论的操作顺序 获取集合的迭代器 修改集合 显然 不是其中的元素 而是集合本身 使用
  • 如何将 BOOST_FOREACH 与两个 std::map 一起使用?

    我的代码基本上如下所示 std map

随机推荐

  • Git Commit提交规范总结

    文章目录 前言git commit 提交规范提交消息头 commit message header 提交消息具体内容 commit message body 提交消息尾述 commit message footer Revert 表情 Em
  • 常用kubectl命令总结

    文章目录 配置kubeconfig帮助信息命令查看具体某一个命令的帮助信息列出全局的选项参数 xff08 适用所有的命令 xff09 显示合并的 kubeconfig 配置或一个指定的 kubeconfig 文件 基本命令罗列所支持的完整资
  • 解决:org.apache.catalina.connector.ClientAbortException: java.io.IOException: 断开的管道

    文章目录 项目场景问题描述原因分析解决方案 项目场景 jdk11 Spring Boot 2 x 项目 xff0c Tomcat容器 Nginx 问题描述 系统日志中 xff0c 时不时会出现下面的异常信息 xff1a org apache
  • 解决:No converter for [xxxx] with preset Content-Type ‘text/plain;version=0.0.4;charset=utf-8‘

    文章目录 项目背景问题描述问题分析解决方案方案一 xff1a 修改Controller定义方案二 xff1a 修改Controller返回值方案三 xff1a 全局处理 项目背景 Spring Boot 2 X 问题描述 错误信息如下 xf
  • SYD8821 串口模块使用说明【串口0中断要屏蔽底层调用】

    SYD8821是具有全球领先低功耗 RX 2 4mA 64 94 5dBm灵敏度 xff0c TX 4 3mA 64 0dBm输出功率 的蓝牙低功耗SOC芯片 xff0c 在极低电流下实现了优异的射频性能 xff0c 搭配176kB SRA
  • MySQL的information_schema库下的常用sql

    文章目录 information schema TABLES查看该数据库实例下所有库大小 MB为单位 查看该实例下各个库大小 MB为单位 查看表大小 MB为单位 熟练使用 information schema库里的表 显示在库里的表 xff
  • shell脚本批量转文件格式:dos2unix

    文章目录 可以使用shell脚本实现 xff1a span class token shebang important bin sh span span class token assign left variable dir span s
  • 解决:com.atomikos.icatch.SysException: Error in init: Log already in use? tmlog in ./

    文章目录 项目场景问题描述原因分析详细分析 解决方案 项目场景 Spring Boot 2 x xff0c 集成 atomikos 问题描述 今天在同一个环境启动两个项目时报错 xff0c 因为两个项目同时涉及到分布式事物和切换数据源相关
  • Nginx日志介绍

    文章目录 access log日志流量统计 access log 日志文件一般存放在 var log nginx 下 xff0c 可以使用 tail f命令查看access日志 span class token function tail
  • JVM (Micrometer)-4701面板参数介绍

    文章目录 Quick Facts 概览 堆和非堆内存有以下几个概念 I O Overview xff08 服务黄金指标 xff09 JVM Memory xff08 JVM内存 xff09 JVM Misc xff08 JVM负载 xff0
  • curl文件传输命令

    CURL curl transfer a URL curl 是一个利用URL语法在命令行下工作的文件传输工具 支持文件上传和下载 格式 curl options URLs URL xff1a 通过大括号指定多个url 示例 xff1a cu
  • RS-485信号解析

    这次来看看RS 485信号 使用绿联的USB转RS485模块 线用的颜色不对 xff0c 类型也不对 xff0c 实际使用中请用带屏蔽层的双绞线 示波器CH1是R xff08 B xff09 示波器CH2是R 43 xff08 A xff0
  • T t与T t = T()的区别

    主要的区别就是默认构造函数对内置类型的初始化上 如果没有T中没有定义构造函数 xff0c 则对于 T t xff0c 并不会对 t 中内置类型设置初始值 xff0c 是一个随机值 但对于 T t 61 T xff0c 对 t 中内置类型会设
  • Effective STL:杂记(一)

    1 避免使用vector lt bool gt vector lt bool gt 实际上并不能算是一个STL容器 xff0c 实际上也并不存储bool 因为一个对象要成为STL容器 xff0c 就必须满足C 43 43 标准的第23 1节
  • 限制长度双向链表的插入操作

    面试遇到的问题 xff0c 一开始面试官是问我有什么方案可以实现排行榜 xff0c 当时给出了两个方案 后面面试官又在我的其中一种方案上让我手写代码实现排序双线链表的插入 xff0c 根据score值插入 xff0c 并且链表长度限制在10
  • SYD8821 IIC模块使用说明

    SYD8821是具有全球领先低功耗 RX 2 4mA 64 94 5dBm灵敏度 xff0c TX 4 3mA 64 0dBm输出功率 的蓝牙低功耗SOC芯片 xff0c 在极低电流下实现了优异的射频性能 xff0c 搭配176kB SRA
  • Python下载文件时出现乱码的解决方法之一:Content-Encoding: gzip

    之前写过一个简单的爬虫程序 xff0c 这次想试着再写一个下载固定文件的爬虫程序 写完之后发现下载的文件 xff0c 有些是可以正常打开的 xff0c 而有些是提示了编码错误 xff0c 用wireshark抓包 xff0c 过滤出http
  • Python爬虫判断url链接的是下载文件还是html文件

    最近在写一个网络爬虫的代码 xff0c 提供命令行来下载文件或者是打印根域名下指定节点及深度的子节点 用的是urllib2库 xff0c 算是比较简单 xff0c 但是功能并没有很强大 说重点吧 xff0c 在实际爬网页的过程中 xff0c
  • recvmsg和sendmsg函数

    在unp第14章讲了这两个函数 xff0c 但是只是讲了两个数据结构及参数而已 xff0c 所以自己想根据介绍来重构udp回射的客户端程序 但是sendmsg和recvmsg都遇到了问题 xff0c 并且纠结了很久 xff0c 所以在此记录
  • STL中map的[]运算导致程序挂掉的问题

    在项目的开发中 xff0c 使用 设置map变量时 xff0c 出现了Segment Fault的问题 xff0c 使用GDB bt命令得到调用栈 xff08 中间部分被我去掉了 xff09 如下 xff1a 0 0x00000000008