Short version
In this code :
QString dataStr;
myfunc(dataStr.toUtf8().constData());
Is the temporary QByteArray object created by toUtf8() destroyed before entering the scope of myfunc() or is it guaranteed to be destroyed after the call to myfunc() is finished?
Long version
I am working with a code similar to this one :
class Request
{
public :
std::function<void()> requestFunc;
};
void myfunc(const char* data)
{
auto request = new Request();
auto lambda = [](const std::string& str)
{
cout << str;
}
// Use data
obj->requestFunc = std::bind(std::move(lambda), std::string(data));
requestQueue.push(std::move(request));
}
QString dataStr;
myfunc(dataStr.toUtf8().constData());
// Some time later, requestQueue gets managed and requestFunc gets called
One the machine of one of my coworkers, it crashed. We resolved this explicitly changing the scope of the temporary QByteArray object created by toUtf8() :
...
QString dataStr;
const QByteArray tempObj = dataStr.toUtf8();
myfunc(tempObj.constData());
And it resolved the crash. But later we a discussion with another coworker, and it isn’t obvious to me if the C++ standard / the compiler is supposed to keep the temporary object until the function call is finished, or if its scope is limited to the parameter, and thus once inside myfunc() the temporary parameter object is already destroyed.
The two possibilities that I see that explain the "fix" of the crash :
- The temp object is indeed destroyed before entering the function, and constData() is pointing to freed memory. As not much happens before it is used, the memory is usually still holding the right value and has not been overwritten. That’s why it was working most of the cases even being wrong, and the new version is the correct fix.
- The temporary object is only destroyed after the function call is finished. It means that the bug is elsewhere, and the "fix" only worked because we delayed the destruction of the temporary object, and thus lowered the likelihood of freed memory being overwritten.
If this is the latter case, than do you know where the bug might be laying?
>Solution :
Is the temporary QByteArray object created by toUtf8() destroyed before entering the scope of myfunc() or is it guaranteed to be destroyed after the call to myfunc() is finished?
The object is not a parameter object. It is a temporary object. A temporary object is destroyed at the end of the full-expression in which it was created, although some exceptions apply, none of which is relevant to this example. Note that a parameter object, i.e. the object corresponding to a non-reference parameter of a function, is not a temporary object and follows other rules.
The end of the full-expression in your example is after the evaluation of myfunc(dataStr.toUtf8().constData()), i.e. at the end of the expression statement.