【发布时间】:2019-10-10 06:58:14
【问题描述】:
我很好奇 shared_ptr 在被 lambda 中的值捕获时的寿命。
只要 lambda 仍在内存中,我曾预计其 use_count() 始终 >= 1,但我的测试显示出一些意想不到的情况:使用计数下降到 0,然后在 lambda 主体内递增到 1...
这是我测试的:
- 创建一个 shared_ptr
- 定义一个按值捕获 shared_ptr 的 lambda
- 重置 shared_ptr
- 运行 lambda
在第 3 阶段,shared_ptr 的 use_count() 下降到 0 - 但对象没有被销毁。在第 4 阶段 - 在 lambda 内部 - use_count() 回到 1。在 lambda 运行后,use_count() 回到 0,但在 lambda 被销毁之前对象不会被销毁。
我想知道这是怎么/为什么会这样?
use_count() 不应该在 lambda 定义之后为 2,然后在 lambda 中为 1?
#include <iostream>
#include <memory>
class Foo {
public:
Foo( int v = 0 ) : val(v) {}
~Foo(){
std::cout << "--- Foo destroyed ---" << std::endl;
}
int val = 0;
};
void logPtr( const std::shared_ptr<Foo>& p ){
std::cout << "ptr: refs = " << p.use_count();
if (p) {
std::cout << ", val = " << p->val << std::endl;
}
else {
std::cout << ", nullptr" << std::endl;
}
}
int main() {
std::shared_ptr<Foo> ptr = std::make_shared<Foo>( 0 );
logPtr(ptr);
std::cout << "--- define lambda ---\n";
auto lambda = [=]() {
std::cout << "--- run lambda ---\n";
if (ptr) { ptr->val++; }
logPtr(ptr);
std::cout << "--- end lambda ---\n";
};
logPtr(ptr);
std::cout << "--- reset ptr ---\n";
ptr.reset();
logPtr(ptr);
// run lambda
lambda();
logPtr(ptr);
}
这是输出:
ptr: refs = 1, val = 0
--- define lambda ---
ptr: refs = 2, val = 0
--- reset ptr ---
ptr: refs = 0, nullptr
--- run lambda ---
ptr: refs = 1, val = 1
--- end lambda ---
ptr: refs = 0, nullptr
--- Foo destroyed ---
【问题讨论】:
-
与 lambda 无关。这是不使用 lambda 的相同代码:repl.it/repls/LonelyDishonestBetaversion。
-
一旦您清除了 shared_ptr 对象,您就无法再获得该对象的使用计数...因为不再指向任何对象(也没有 shared_counter)。
标签: c++ c++11 lambda shared-ptr