为什么"weak.lock()"返回"nullptr" "auto weak=std::make_shared<int>(42);"的定义?
Why does "weak.lock()" return "nullptr" with the definition of "auto weak=std::make_shared<int>(42);"?
为什么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
及其控制块都保持活动状态。因此,只要sharedPtr
(或其任何副本(不被销毁,就可以锁定weakPtr2
。
您的示例使用副本初始化。因此,建立在正确基础上的shared_ptr
只存在到表达式的评估,然后被破坏:
- 在第一个例子中,这意味着不再有对shared_ptr的引用(我们不计算弱的(,因此
lock
返回 null。 - 在第二个中,您将结果绑定到局部变量,将生命周期延长到当前块 - 因此仍然有一个引用,并且没有空结果。
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 没有显式声明的int[]中的foreach
- 在c++中访问int到类对象的映射时出错
- 为什么我无法更改"set<set>"循环中的值<int>
- 长 长 int 不要 长 int 好
- C++程序在循环后给出奇怪的int值
- 如何计算数据类型的范围,例如int
- 如果"new int"返回"int*",那么为什么"new int[n]"不返回"int**"?
- 为什么"weak.lock()"返回"nullptr" "auto weak=std::make_shared<int>(42);"的定义?