首先,如果这看起来很明显,请原谅我 - 我是C ++的新手。我一直在寻找这个,但我还没有发现任何特别有用的东西。
当尝试访问lambda中的捕获变量时,我的应用程序崩溃了,我不明白为什么。我不认为该对象已被删除,因为在断点处崩溃并使用CLion的调试器时,CLion会显示该对象存在。
代码示例可能会帮助我解释一下:
//Create the progress dialog
QProgressDialog *progDialog = new QProgressDialog(tr("Opening Project…\nExtracted: 0 (0.0%)\nWaiting…"), nullptr, 0, 0, this);
// ... Some code here
//Declare a function to be passed as a callback
std::function<void (int minValue, int maxValue)> *progRangeChangedCallback = nullptr;
// ... More code here
//Create the lambda
//I capture progDialog (The progress dialog)
auto progRangeChangedCallbackLambda = [&progDialog](int newMin, int newMax) {
//Putting a breakpoint here reveals that progDialog exists
//CLion even autocompletes the below functions
//when trying to evaluate an expresion
progDialog->setMinimum(newMin); //EXC_BAD_ACCESS: Crashes happen here!
progDialog->setMaximum(newMax);
};
// ... Even more code here
//Put the lambda in a std::function
progRangeChangedCallback = new std::function<void (int minValue, int maxValue)>(progRangeChangedCallbackLambda);
// ... More code
//Pass the std::function object as a callback to a new thread
//This extends QThread
OpenProjectThread *thread = new OpenProjectThread(filePath, this, progChangedCallback, progRangeChangedCallback, onSuccessCallback, onErrorCallback);
thread->start();
答案 0 :(得分:3)
lambda通过引用捕获progDialog
。这意味着如果声明progDialog
的范围终止,那么progDialog
不再有效,而是为lambda留下悬空引用。显示的代码不足以得出权威答案,但这似乎是最可能的答案。
并不能肯定地说progDialog
应该通过值来捕获。即使它被价值捕获,progDialog
得到delete
d,kaboom!这里没有给出权威结论的信息。
对C ++有点新鲜的人#34;会发现花更多时间学习基本原则(如范围规则,指针和引用)更有用,它们支持语言的高级功能,如lambdas和lambda捕获。在开始兼顾所有这些lambda之前,你必须了解所有这些是如何工作的。