在 wifstream 析构函数中中止

Posted

技术标签:

【中文标题】在 wifstream 析构函数中中止【英文标题】:Abort in wifstream destructor 【发布时间】:2018-03-21 17:43:08 【问题描述】:

以下 C++ 代码在执行 return 时出现神秘错误(“调试错误!...abort() 已被调用”)。这是 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变量。

【问题讨论】:

这个“程序”不是程序;这是一个代码sn-p。添加足够的代码,以便编译和运行并显示问题。 如果您在销毁后尝试使用使用cv1 的地址灌输的流,则可能会失败。但在我们看到您的minimal reproducible example 之前,我们无法确定这一点。您已经在这里待了足够长的时间来理解为什么需要一个。 【参考方案1】:

std::locale 为与之关联的每个方面维护一个引用计数。您正在调用的std::locale 构造函数将增加您传入的std::codecvt_utf16 对象的引用计数,然后std::locale 的析构函数将减少该引用计数。当std::codecvt_utf16 的引用计数降为0 时,将通过delete 操作符将其销毁。这就是您收到中止错误的原因 - 当 std::wifstream 析构函数清理 imbue'd 语言环境时,该语言环境的析构函数尝试使用 delete 开始时未使用 new 运算符分配的内容。

改为这样做:

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

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

【讨论】:

Tnx 为您的提示(和正确!)响应。当我编译你的代码时,我得到一个error C2661: 'std::_Crt_new_delete::operator new': no overloaded function takes 3 arguments。这来自 Visual Studio 放入对话框源文件的`#ifdef _DEBUG / #define new DEBUG_NEW / #endif`。删除它编译并运行没有错误。所以有一些 Visual Studio 不兼容。 我提供的代码没有将 3 个参数传递给new,无论new 被定义为什么,它都应该编译。否则 VS 会破坏核心语言功能。 DEBUG_NEW 定义为什么?我不使用VS。 #define DEBUG_NEW new(THIS_FILE, __LINE__)#define THIS_FILE __FILE__。而且,是的,这是 VS 中的一个错误,我将报告。你的代码没有错! 这种DEBUG_NEW 可以像这样工作的唯一方法是,如果在具有三个参数的范围内有一个重载的operator newvoid* operator new (size_t size, const char *filename, int line)(请参阅this example)。听起来您的情况并非如此,这可以解释您看到的编译器错误。

以上是关于在 wifstream 析构函数中中止的主要内容,如果未能解决你的问题,请参考以下文章

STL 字符串中止的析构函数

可连接 std::thread 的析构函数

unity c#怎么调用析构函数

05.析构函数

C语言里面构造函数和析构函数的运用办法

构造函数和析构函数