2016-08-20 121 views
0

首先,請原諒,如果這看起來很明顯 - 我對C++很陌生。我一直在尋找這個,但我沒有發現任何特別有用的東西。EXC_BAD_ACCESS with lambda capture

當試圖訪問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(); 

回答

2

拉姆達通過參考捕捉progDialog。這意味着如果progDialog獲取聲明的範圍終止,那麼progDialog不再有效,從而使lambda具有懸空引用。顯示的代碼不足以得出權威的答案,但這似乎是最可能的答案。

而且不能肯定地說progDialog應該在這裏被值捕獲。即使它被價值捕獲,progDialog得到delete d,kaboom!根本沒有這裏給出的信息來作出權威性的結論。

對於「對C++來說是一種新鮮感」的人會發現,花更多時間研究基本原則(如範圍規則,指針和引用)是支持語言的高級功能的基本原則(如lambda和lambda)捕獲。在開始處理所有這些lambda之前,你必須瞭解所有這些工作。