C++ 智能指针 std::shared_ptr 的指针引用和指针有效性

文章探讨了C++中std::shared_ptr在多线程环境下的行为,尤其是在线程2修改并删除元素后,线程1如何访问已被删除的元素。实验表明,即使智能指针被销毁,引用仍可访问同一地址,直到引用计数为0。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础代码

t1线程首先执行 DoIt ,并将链表最后一个元素传入进去,然后轮询is_l,

t2线程首先休眠3秒(保证1线程先跑),然后将链表中值为3和5的元素删除,置is_l为1。

t1此时轮询结束,查看i1的值,由于t2已经将5给删除了,那么t1在这之后访问值为5的元素还能成功吗?

bool is_l = false;

void DoIt(std::shared_ptr<int> &i1) {
  while (!is_l) {
  }
  std::cout << "loop: " << i1 << std::endl; // loop: 0x562e787763b0
  std::cout << *i1 << std::endl;
}
/** IS, IS, X integration test */
void MyPointTest() {
  // 定义一个 全局链表
  std::list<std::shared_ptr<int>> l1;
  // 插入数据
  l1.push_back(std::make_shared<int>(1));
  l1.push_back(std::make_shared<int>(2));
  l1.push_back(std::make_shared<int>(3));
  l1.push_back(std::make_shared<int>(4));
  l1.push_back(std::make_shared<int>(5));

  // 定义两个线程
  std::thread t_1([&]{
    DoIt(l1.back());
  });
  std::thread t_2([&]{
    // 线程2 休眠一会,然后再启动并且执行一些操作
    std::this_thread::sleep_for(std::chrono::seconds(3));
    for(auto it=l1.begin();it!=l1.end();++it){
      if(**it==3){
        l1.erase(it);
        break;
      }
    }
    for(auto it=l1.begin();it!=l1.end();++it){
      if(**it==5){
        std::cout << "5: " << *it << std::endl
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值