• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2025-05-30 22:22 Aet 隐藏边栏 |   抢沙发  4 
文章评分 3 次,平均分 5.0

概述

  1. 关于shared_ptr智能指针对象管理内存的情况
    1. 不同的shared_ptr对象管理不同的内存
    2. 多个shared_ptr对象管理同一块内存
  2. 对于管理不同的内存
    1. 因为每个shared_ptr对象都有各自的控制块,因而引用计数独立,所有不存在问题
  3. 对于管理同一块内存
    1. 因为每个shared_ptr对象都有各自的控制块,因为引用计数独立,但是它们之间不会同步这个引用计数的改动,所有会存在问题

示例

问题1

  1. 其中一个shared_ptr对象的引用计数为0时,它会释放管理的内存
  2. 于是,多个shared_ptr对象指向的同一块内存,此时已经被释放了
  3. 但是,由于控制块不同,引用计数不同步,其他的shared_ptr对象的引用计数此时可能还不为0
  4. 于是,引用计数不为0,该shared_ptr对象认为所管理的内存还没被释放,它访问了该内存
  5. 导致访问已释放内存(野指针)

问题2

  1. 其中一个shared_ptr对象的引用计数为0时,它会释放管理的内存
  2. 于是,多个shared_ptr对象指向的同一块内存,此时已经被释放了
  3. 但是,由于控制块不同,引用计数不同步,其他的shared_ptr对象的引用计数此时可能也刚好为0
  4. 于是,引用计数为0,那就要释放管理的内存,所以该shared_ptr对象对已经释放的内存再次释放
  5. 导致双重释放(程序崩溃)

解决

  1. 使用std::enable_shared_from_this

std::enable_shared_from_this

  1. 当你的类继承 std::enable_shared_from_this 后:
    1. 所有通过 shared_from_this() 生成的 shared_ptr 共享同一个控制块:
      shared_from_this() 会返回一个与已有 shared_ptr 共享控制块的智能指针
      即使多次调用 shared_from_this(),所有生成的 shared_ptr 都会引用同一个控制块
    2. 引用计数同步:
      所有 shared_ptr 共享同一个引用计数,确保对象只在所有引用计数归零时释放一次

  1. 注意
    1. 在调用 shared_from_this() 之前,对象必须已经由一个 shared_ptr 管理(例如通过工厂方法创建):
    2. 就是说,类继承了enable_shared_from_this之后,要先创建一个shared_ptr对象,确保它被shared_ptr管理,然后之后的shared_ptr再通过shared_from_this来创建

  1. 示例

声明:本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享