在 wifstream 析构函数中中止

Abort in wifstream destructor

本文关键字:析构函数 wifstream      更新时间:2023-10-16

以下C++代码收到一个神秘的错误("调试错误...abort(( 已被调用"(在执行return时。这是Visual Studio 2017 15.6.3,该程序是64位调试版本,在64位Windows 7下运行。导致此错误的原因是什么,我该如何解决?

wifstream inFile;
std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian> cv1;
inFile.imbue(std::locale(inFile.getloc(), &cv1));
return 0;

使用调试器跟踪显示消息来自反汇编器指令

call        std::basic_ifstream<wchar_t,std::char_traits<wchar_t> >::`vbase destructor'

堆栈上的最后一个条目(除 msvcp140d.dllvcruntime140d.dllucrtbased.dll 之外是

    MyApp.exe!std::basic_ifstream<wchar_t,std::char_traits<wchar_t> >::`vbase destructor'() C++

这段代码的目的是输入文件infile是Unicode(小端序(,我正在将其读入std::string变量中。

>std::locale维护与其关联的每个方面的引用计数。 您正在调用的构造函数std::locale将递入您传入的std::codecvt_utf16对象的引用计数递增,然后 std::locale 的析构函数将递减该引用计数。 当std::codecvt_utf16的引用计数下降到 0 时,它将通过 delete 运算符销毁。 这就是您收到中止错误的原因 - 当std::wifstream析构函数清理imbue的区域设置时,区域设置的析构函数会尝试delete未与new运算符一起分配的内容。

请改为执行以下操作:

inFile.imbue(std::locale(inFile.getloc(),
    new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>));

请参阅有关 cppreference.com 的std::codecvt_utf16文档中的示例。