简体   繁体   中英

EXC_BAD_ACCESS with lambda capture

First of all, excuse me if this seems obvious - I'm sort of new to C++. I have been looking in to this, but I haven't found anything that was particulary helpful.

When trying to access a captured variable within a lambda, my application crashes and I have no idea why. I don't think that the object has been deleted, as when putting a breakpoint where it crashes and using CLion's debugger, CLion shows that the object exists.

A code sample will probably help me explain this:

//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();

The lambda captures progDialog by reference. Which means that if the scope, where progDialog gets declared, terminates, then progDialog is no longer valid, leaving the lambda with a dangling reference. The shown code is insufficient to draw an authoritative answer, but this seems to be the most likely answer.

And it cannot be certain to say that progDialog should be captured by value here. Even if it's captured by value, and progDialog gets delete d, kaboom! There's simply not information given here to make an authoritative conclusion.

Someone who's "sort of new to C++" will find it more useful to spend more time studying fundamental principles -- like scoping rules, pointers, and references -- that underpin the advanced features of the language, like lambdas and lambda captures. You have to understand how all of that works, before starting to juggle all these lambdas around.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM