STL容器保存智能指针并将this指针通过emplace传入STL容器所造成的致命问题(【double free or corruption (out)】和【bad_weak_ptr】)

2023-05-16

我用std::queue保存了一个Message类型的智能指针(queue<shared_ptr<MessageA>),然后在Message类型中来将this指针插入队列,使用std::queue::push(this)不可以通过编译,而使用std::queue::emplace(this)却可以,因此便使得问题在pop()时出现:造成double free or corruption (out) 错误

#include<iostream>
#include<queue>
#include<memory>

using namespace std;

// 传递智能指针,有问题,因为std::queue::pop会析构/释放智能指针
static queue<shared_ptr<class MessageA>> QA;

// 传递裸指针,没问题,因为std::queue不会析构/释放裸指针
// static queue<class MessageA*> QA;

class MessageA {
public:
    explicit MessageA(int m): msg{m} {}

    void produce() {
        QA.emplace(this); //! pop时会出现错误:double free or corruption (out)
        cout << QA.front().use_count() << endl;
    }

    int msg;
};

int main() {
    auto messageA = std::make_shared<MessageA>(1);
    messageA->produce();
    QA.pop(); // error: double free or corruption (out)
}

试着用enable_shared_from_thisshared_from_this来解决:失败,pop时会出现异常:bad_weak_ptr

#include<iostream>
#include<queue>
#include<memory>

using namespace std;

// 传递智能指针,有问题,因为std::queue::pop会析构/释放智能指针
static queue<shared_ptr<class MessageB>> QB;

// 传递裸指针,没问题,因为std::queue不会析构/释放裸指针
// static queue<class MessageB*> QB;

// 试图使用enable_shared_from_this来解决:失败
class MessageB: enable_shared_from_this<MessageB> {
public:
    explicit MessageB(int m): msg{m} {}

    void produce() {
        QB.emplace(shared_from_this());  //! pop时会出现异常:bad_weak_ptr
    }

    int msg;
};

int main() {
    auto messageB = std::make_shared<MessageB>(2);
    messageB->produce();
    QB.pop(); // exception: bad_weak_ptr
}

最后发现,该问题本质上相当于:

int * a = new int{};
shared_ptr<int> a1{a};
shared_ptr<int> a2{a};

// 函数结束时析构shared_ptr,也会造成double free错误

这个问题相信用智能指针的人都知道不能这么做,应该在shared_ptr构造时new,而不是像上面这样,会使得引用计数为1而不是为2。

而最上面的代码却通过emplace(this),使用原生指针构造了一个智能指针,而这个智能指针不与任何指针共享引用计数,最后便会产生double free错误。

由于本人才疏学浅,目前还没找到解决办法(也懒得找),但是有一个结论是肯定的:不要将原生指针(特别是this)传递给智能指针

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

STL容器保存智能指针并将this指针通过emplace传入STL容器所造成的致命问题(【double free or corruption (out)】和【bad_weak_ptr】) 的相关文章

随机推荐

  • 达梦数据库sql语句记录

    登入 在ubuntu上安装好达梦数据 xff0c 并且生成实例 xff0c 在ubuntu上进行安装目录 xff0c 采用在tools目录下 xff0c 使用 disql进行命令行模式 xff0c 连接服务器 xff1a Conn sysd
  • vertx web开发(一)

    vertx web开发 最近在开发中 xff0c 由于spring 的大而全 xff0c 反而不实用于一下小项目 xff0c 因为spring boot在空载的情况 xff0c 至少其内存占用超过150M 而对于一些简单的项目反到不适用 而
  • kotlin协程实现原理

    传统runnable接口实现 在java中 xff0c 很多耗时的行为通过实现runnable接口 xff0c 并且通过线程运行下这些耗时的任务 xff0c 例如 xff1a span class token keyword public
  • PCL---RANSAC随机采样一致性算法

    前言 通过前面的文章 xff0c 我们基本上代建的相关环境 本文将继续基于此继续学习PCL相关采样一致性算法 基础代码下载 1 准备 1 1 Ransac算法介绍 RANSAC从样本中随机抽选出一个样本子集 xff0c 使用最小方差估计算法
  • PCL-使用potree可视化

    前言 在几篇文章中 xff0c 基本实现了对PCL相关操作 xff0c 最近在github上找到了Web端对点云数据可视化兼容很好的项目 Potree 对此本文将介绍如何使用Potree来进行web端的可视化 1 Potree 官方运行 P
  • PCL- Las文件处理

    前言 在对点云数据处理的时候 xff0c 很多时候激光雷达扫描的文件不一定是 pcd文件 xff0c 这个时候需要进行相关文件处理 xff0c 如Las xff0c laz e57等文件格式 xff0c 本文将介绍las文件的读写 1 引入
  • PCL-Window下安装

    1 安装编译工具链MSVC MSVC工具链是visual studio 自带的工具链 xff0c 因此安装visual studio社区版即安装完成相应的MSVC工具链 2 安装Clion 相比与Visual studio的界面来说 xff
  • STM32 串口详细讲解

    什么是串口 UART Universal Asynchronous Receiver Transmitter 通用异步收发器 USART Universal Synchronous Asynchronous Receiver Transmi
  • ubuntu 修改pip指定路径

    参考这篇文章 还有 这篇文章 第二篇更好一点 xff0c 亲测成功
  • CrowdHuman数据集介绍

    CrowdHuman数据集是旷世发布的用于行人检测的数据集 xff0c 图片数据大多来自于google搜索 CrowdHuman 数据集数据量比较大 xff0c 训练集15000张 xff0c 测试集5000张 xff0c 验证集4370张
  • CityPersons数据集介绍

    CityPersons数据集是cityscape的一个子集 xff0c 它只包含个人注释 有2975张图片用于培训 xff0c 500张和1575张图片用于验证和测试 一幅图像中行人的平均数量为7人 xff0c 提供了可视区域和全身标注 C
  • CUHK-SYSU数据集介绍

    该数据集是一个大规模的人员搜索基准 xff0c 包含18184张图像和8432个身份 根据图像来源 xff0c 数据集可以分为两部分 xff1a 街道捕捉和电影 xff1a 在街拍中 xff0c 图像通过手持摄像机收集 xff0c 跨越数百
  • ETHZ数据集介绍

    Ess等构建了基于双目视觉的行人数据库用于多人的行人检测与跟踪研究 该数据库采用一对车载的AVT Marlins F033C摄像头进行拍摄 xff0c 分辨率为640 480 xff0c 帧率13 14fps xff0c 给出标定信息和行人
  • Swin Transformer V2

    Swin Transformer V2 论文链接 xff1a https arxiv org pdf 2111 09833 pdf 代码链接 xff1a https github com microsoft Swin Transformer
  • Jetson_Xavier_NX使用教程1(刷机)

    刷机教程 一 xff1a 准备 1 xff1a 准备需要一个tf卡 xff0c 容量最好大点 xff0c 我买的128G的 2 xff1a 还有两个软件一个是格式化卡的软件 xff0c 一个是将镜像文件写入的卡的软件 格式化卡的软件 写入镜
  • Jetson_Xavier_NX使用教程2(简单实用)

    本文会介绍一些刷机后的基本操作 1 风扇控制 刚开始插入电源风扇不转我以外坏了 xff0c 后来才发现并没有 Xavier NX的风扇在系统内核中有一套自动控制温度和转速的算法 xff0c 经过我观察大约在40度左右的时候会自动开启风扇进行
  • NVIDIA Jetson NX使用教程3配置pytorch环境

    本节主要记录 xff0c 安装pytorch及torch vision 1 下载Pytorch 因为jetson属于arm架构的机器 xff0c 所以需要去nvidia的官网下载对应的安装包而不是pytroch的官网 官网链接 xff0c
  • Java 基于 IETF RFC 2617 身份认证

    IETF RFC 2617 身份认证 是基于 HTTP 协议进行验证的 xff0c 认证过程中需要发送两次 HTTP 请求 xff0c 第一次请求服务器返回 401 和 认证标识 xff08 nonce xff09 xff0c 第二次访问H
  • 判断一台机器是大端序还是小端序

    在几乎所有的机器上 xff0c 多字节对象都被存储为连续的字节序列 例如在C语言中 xff0c 一个类型为int的变量x地址为0x100 xff0c 那么其对应地址表达式 amp x的值为0x100 且x的四个字节将被存储在存储器的0x10
  • STL容器保存智能指针并将this指针通过emplace传入STL容器所造成的致命问题(【double free or corruption (out)】和【bad_weak_ptr】)

    我用std queue保存了一个Message类型的智能指针 queue lt shared ptr lt MessageA gt xff0c 然后在Message类型中来将this指针插入队列 xff0c 使用std queue push