qt C++ exception on basic_string destructor on double click run only

眉间皱痕 提交于 2019-12-10 11:41:34

问题


I have following code:

CAtlString str = currentFolder->whatsThis().toStdWString().c_str();

currentFolder is qt QTreeWidgetItem*. When I run program from VS2010 it works ok. But when I start program by double click in the same folder (x64/Debug or Release), I have exceptions:

Unhandled exception at 0x00007ffe2a07572a (ntdll.dll) in test.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.

on dealloc in basic_string destructor:

~basic_string()      // xstring
    {   // destroy the string
    _Tidy(true);
    }

// ...

void deallocate(pointer _Ptr, size_type) // in xmemory
    {   // deallocate object at _Ptr, ignore size
    ::operator delete(_Ptr);
    }

I`m trying to delete string directly, clean, erase - but every time I had the same result. Also I had tried to use different runtimes and deploy packages, without lucky. (searched with Dependency Walker). Why program works under VS2010? And how can I fix standalone running? thx!

Update This is the minimal code reproduced the problem: zalil.ru use x64 config and run program by double click for catch the exception.

Update2 if I keep wstring pointer alive (using temp variable), I have following error:


回答1:


When you debug your app in Visual Studio with your default project settings, working folder is set to folder, where your sources are. And when you run app standalone, working folder is folder where your exe file is.

Error says it fails to deallocate std::wstring, which is made from QString::toStdWstring() method. QString is returned by whatsThis() method. As std::wstring is invalid, QString is also invalid. If currentFolder pointer is a valid pointer, it couldn't return invalid QString. So currentFolder is an invalid pointer.

Considering your working dir changed, probably currentFolder wasn't initialized properly.




回答2:


When you use what .c_str() returned you are using dangling pointer, as std::wstring object gets destroyed, but pointer, which c_str() returned still lives. c_str() returns inner pointer, memory to which it points is destroyed in std::wstring's destructor.

Accessing a dangling pointer is UB, that's why you never know will memory it points to be still valid or not

Workaround: keep std::wstring until you doesn't need c_str() anymore:

auto temp = currentFolder->whatsThis().toStdWString();
CAtlString str = temp.c_str();



回答3:


I have found problem solution. As I can understood, on my computer I have mixed installed Qt libraries (3 different versions) and when std::string destructor called, I have UB because wrong runtime called. To solve my problem, I need to avoid using toStdWString/c_str in QString conversions //for example like this auto arr = currentFolder->whatsThis().toUtf8(); std::string temp_str(arr.data()); qDebug() << temp_str.c_str();

or recompile/clean reinstall all libraries that I have used. Its so strange configuration error) There is the page with decision: forum.qt.io



来源:https://stackoverflow.com/questions/38076334/qt-c-exception-on-basic-string-destructor-on-double-click-run-only

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!