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?
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
request->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 :
If this is the latter case, than do you know where the bug might be laying?
EDIT :
It turns out the bug was with my previous code. Before the change I was doing this :
QString dataStr;
const char* dataPtr = dataStr.toUtf8().constData();
myfunc(dataPtr);
So the temporary object was being destroyed before the call to myfunc()
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.
In your modified example in the question edit, the end of the full-expression in which dataStr.toUtf8()
's result object is materialized is after the initialization of the variable dataPtr
, which means that in the following call myfunc(dataPtr)
, the object is already destroyed and dataPtr
is dangling.