【发布时间】:2026-01-10 19:35:01
【问题描述】:
我简化了代码,请原谅我的风格。
我想知道当这个 lambda 本身是另一个线程的回调时,由实际分配内存并按值传递给 lambda 的构造函数构造的对象会发生什么情况。 当调用析构函数时看到程序崩溃并不让我感到惊讶。这是测试#1。
test#2:我从 A 的 c'tor 和 d'tor 中删除了“new”和“delete[]”,现在 - 它工作正常。
测试#3: 我像以前一样带回了“new”和“delete[]”,但是现在我将每个带有“A objA”(按值)的地方都改成了“A& objA”,现在它也没有崩溃了。
现在,我可以通过挥手使其合理化,但我想了解这里真正发生了什么,就此而言 - 如果通过“捕获”传递给 lambda 的对象也停止存在。
最后一个问题:在这种情况下,有没有好的做法或提示应该做什么(或避免什么)?
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
using namespace std::chrono_literals;
class A {
public:
A() : x(1) { ptr = new char[1024]; }
~A() { delete[](ptr); }
int getX() { return x; }
private:
int x = 0;
char* ptr = nullptr;
};
std::function<void(A objA)> myCb;
int myThread()
{
static int counter = 0;
auto a = new A;
while (true) {
std::this_thread::sleep_for(2s);
if (myCb)
myCb(*a);
else
std::cout << "myCb is still NULL: counter = " << counter << std::endl;
if (counter++ == 5)
break;
}
return 0;
}
void registerCallback(std::function<void(A obj)> cb)
{
myCb = cb;
}
int main()
{
std::thread t1(myThread);
std::this_thread::sleep_for(6s);
int val = 5;
registerCallback([&val](A objA) {
std::cout << "here lambda is called with " << objA.getX() << " and " << val << std::endl;
});
val = 6;
std::this_thread::sleep_for(1s);
val = 7;
std::this_thread::sleep_for(1s);
val = 8;
std::this_thread::sleep_for(1s);
t1.join();
}
【问题讨论】:
-
我不认为在没有同步的情况下允许在另一个线程中读取
std::function时分配给它。
标签: c++ lambda callback pass-by-reference pass-by-value