在 Qt 中使用 std::string 会导致销毁时出现运行时错误

发布于 2024-08-22 17:38:37 字数 553 浏览 11 评论 0原文

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

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

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

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

即使使用空的 std::string ,到 QString 的转换也可以正常工作。

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

(在其他线程中,有些人讨论了调试和发布库的混合,但我认为我没有这样做。顺便说一句,如何找出?)

I have a Qt app that uses another library where the function output is std::string instead of a QString.

So in my program I have a method

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

When my external lib returns a not-empty std::string everything works fine.
But when an empty std::string is returned, the app crashes at the end of the scope. I guessed that has to do with destruction of the std::string object(?).

The conversion to QString works fine, even with an empty std::string.

Can someone tell my why this happens, and how to avoid this run-time error?

(In other threads some people have discussed mixing of debug and release libraries, but I dont think that I have done that. How to find out btw?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云胡 2024-08-29 17:38:37

解决方案是确保您的 Qt 版本是使用您的应用程序所使用的同一编译器进行编译的。

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

因此,只需配置您的版本,然后使用 VS2010 编译器重新制作即可。

The solution is to make sure your Qt version is compiled with the same compiler you are using for your application.

In my case, I downloaded Qt 4.7.3 which was pre-built with VS2008. When I moved to VS2010, toStdString was causing my app to crash. I would also get some other strange errors with STL strings.

So, simply configure your release, and re-make it with the VS2010 compiler.

亚希 2024-08-29 17:38:37

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

Use "dependency walker" to see on which DLL's your application (and the external DLL, and the QT DLL) are relying.

千紇 2024-08-29 17:38:37

您需要使用 Dependency Walker(Patrick 建议)查看不同版本的 msvc 运行时库(msvcrt 和朋友),以及它们是否被不同的 dll 使用,而这些 dll 恰好交换内存他们之间。

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

因此,如果您在一个 dll 中分配内存(例如,通过创建一个超过 16 个字符的 std::string)并将其发送到另一个 dll,并在该 dll 中终止(在作用域末尾),则删除调用将转到堆与 new:ed 的堆不同,并且会发生崩溃。

因此,为了在 Windows 上跨 DLL 兼容 STL,必须使用相同的编译器。

如果 DLL 公开一个始终可以释放其自己的内存的 API,则不存在此类问题。 (即认为 COM,或类似但不那么丑陋的东西)。

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

What you need to look using the Dependency Walker (which Patrick suggests) for is different versions of the msvc runtime libs (msvcrt and friends), and if they're used by different dll's that happen to exchange memory between them.

This is the crucial part, since the heap is kept in the runtime dll, each runtime will have it's own heap (i.e. for vs 2008, 2010, 2005).

So, if you allocate memory in one dll (say by creating a std::string with more than 16 or so characters) and send it to another dll where it dies (at the end of scope), the delete call will go to a different heap than from where it was new:ed, and crashes ensue.

So, for STL compatibility across DLLs on windows, the same compiler must be used.

If a DLL exposes an API where it always can free it's own memory, there is no such problem. (i.e. think COM, or something similar but less hideous).

There could also be ABI incompatibilities, but I'm not so sure about those. Over the years, I've mostly been bitten by memory allocation/freeing issues.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文