(42);"的定义?-6ren"> (42);"的定义?-为什么weak.lock()返回 nullptr在此代码片段中: std::weak_ptr weakPtr1 = std::make_shared(6); std::cout shar-6ren">
gpt4 book ai didi

c++ - 为什么 "weak.lock()"返回 "nullptr"与 "auto weak=std::make_shared(42);"的定义?

转载 作者:行者123 更新时间:2023-12-01 13:30:14 29 4
gpt4 key购买 nike

为什么weak.lock()返回 nullptr在此代码片段中:

   std::weak_ptr<int> weakPtr1 = std::make_shared<int>(6);
std::cout << weakPtr1.lock() << std::endl;

而它在以下情况下工作:
   std::shared_ptr<int> sharedPtr = std::make_shared<int>(99);
std::weak_ptr<int> weakPtr2 = sharedPtr;
std::cout << weakPtr2.lock() << std::endl;

检查 cpp.sh/9gkys。

我曾经想过,想过,但我现在仍然很困惑。我将不胜感激能在这个问题上得到一些帮助。

最佳答案

智能指针,为了正常工作,维护一个所谓的控制块,作为元数据存储,特别是使用计数器。也就是说,每个资源在内存中都有一个关联的控制块(由例如两个整数组成),智能指针可以引用它来了解它们中有多少仍在使用/观察资源。显然,每个存在std::shared_ptr增加存储在控制块中的使用计数器,以便其析构函数知道是否是在销毁时释放资源的时间。 std::weak_ptr ,反过来,只跟踪对象及其控制块。请注意,这里有一个重要的细节:std::weak_ptr不增加使用计数器。这是可取的,因为它的主要目的是打破一对相互观察的对象之间可能的循环。也就是说,如果两个对象将存储 std::shared_ptr一个对一个,那么这样一对对象也将永生不息。

怎么可以std::weak_ptr知道资源是否可以lock()编辑?只有当使用计数器大于零时,这才能成功。它从控制块(它本身在内存中保持事件状态,只要还有非零弱指针观察它)就知道了。

在第一个例子中:

std::weak_ptr<int> weakPtr1 = std::make_shared<int>(6);

分配了资源( int=6 )及其控制块。使用计数器变为 1 ,并且只要 std::shared_ptr 就保持不变活着。然后,一个 std::weak_ptr被初始化,获得一个指向控制块的指针。在这里,它不会增加使用计数器。然而,它会增加弱指针的计数器。此时,两个计数器都是 1 .然后,在分号 ; ,临时 std::shared_ptr被摧毁。它将使用计数器减少到 0 .这意味着不再有共享资源的所有权的共享指针,这允许释放该资源。但是,还有 1弱指针观察控制块,这意味着控制块本身会留在内存中,所以 weakPtr1知道它不能 lock()资源(因为该资源不再存在)。

在第二个例子中:
std::shared_ptr<int> sharedPtr = std::make_shared<int>(99);
std::weak_ptr<int> weakPtr2 = sharedPtr;

双方资源 int=99并且它的控制块保持事件状态。因此 weakPtr2只要 sharedPtr即可锁定(或其任何拷贝)不会被销毁。

关于c++ - 为什么 "weak.lock()"返回 "nullptr"与 "auto weak=std::make_shared<int>(42);"的定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62401405/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com