- 在 Windows 下应用 VS 开发 QT 程序,如果应用了函数 toStdString 来将 QString 转换为 std::string 的时候,可能会产生解体,报错__acrt_first_block == header。
- 这种解体会产生在 vs 我的项目的运行库设置为动态链接(/MT)时,如果运行库设置的是动静链接(/MD)则不会有问题。
- 这个解体的根本原因是对象在析构时开释内存不正确。std::string 是 STL 中定义的模板类,所以编译器在编译 dll 时会将 std::string 实例化,在编译 exe 时也会将其实例化。当设置运行库为动态链接(/MT)时,dll 和 exe 都有本人独立的 heap 内存。函数 toStdString 会返回一个 std::string,这个 std::string 是在 dll 的内存中调配的,当其在 exe 中被开释时就会抛出__acrt_first_block == header 的异样。
- 这个问题在 QT 的官网 bugreports 里也有人反馈——QString::toStdString() bug——依照官网的说法这不是 QT 的 bug,是微软编译器的实现问题。
-
所以,这个问题的解决办法就是:
- 设置 dll 和 exe 的运行库为动静链接(/MD)。
- 让 dll 的接口不要返回 std::string。
-
应用 toLocal8Bit 替换 toStdString。例如, 将
std::string fs = qsFilter.toStdString();
批改为
std::string fs = std::string(qsFilter.toLocal8Bit());