使用带有Qt的std :: string会导致销毁时出现运行时错误

时间:2010-02-25 10:45:59

标签: destructor runtime-error stdstring qstring

我有一个使用另一个库的Qt应用程序,其中函数输出是std :: string而不是QString。

所以在我的程序中我有一个方法

void doSomething() {
...
std::string std_string = MyExternalLibraryThatReturnsSTLstring.getString();
QString myQString = QString::fromStdString(std_string);
...
process(myQString);
...
}

当我的外部lib返回一个非空的std :: string时,一切正常。 但是当返回一个空的std :: string时,应用程序会在范围的末尾崩溃。我猜这与破坏std :: string对象(?)有关。

转换为QString工作正常,即使是空的std :: string。

有人可以告诉我为什么会发生这种情况,以及如何避免这种运行时错误?

(在其他线程中,有些人讨论了调试和发布库的混合,但我不认为我已经这样做了。如何找到btw?)

3 个答案:

答案 0 :(得分:1)

解决方案是确保使用与应用程序相同的编译器编译Qt版本。

就我而言,我下载了Qt 4.7.3,它是用VS2008预先构建的。当我搬到VS2010时,toStdString导致我的应用程序崩溃。我还会在STL字符串中得到一些其他奇怪的错误。

因此,只需配置您的版本,并使用VS2010编译器重新制作它。

答案 1 :(得分:0)

使用“dependency walker”查看您的应用程序(以及外部DLL和QT DLL)所依赖的DLL。

答案 2 :(得分:0)

使用Dependency Walker(Patrick建议)需要查看的是msvc运行时库(msvcrt和朋友)的不同版本,如果它们被不同的dll用于交换内存< / strong>他们之间。

这是关键部分,因为堆保存在运行时dll中,每个运行时都有自己的堆(即vs 2008,20010,2005)。

所以,如果你在一个dll中分配内存(比如通过创建一个超过16个左右的字符的std :: string)并将它发送到它死的另一个dll(在范围的末尾),删除调用将转到不同的堆,而不是新的:ed,然后崩溃。

因此,对于Windows上DLL的STL兼容性,必须使用相同的编译器。

如果DLL公开了一个API,它总是可以释放它自己的内存,那么就没有这样的问题。 (即思考COM,或类似的东西,但不那么可怕)。

也可能存在ABI不兼容性,但我对这些不太确定。多年来,我大多被内存分配/释放问题所困扰。