Я наткнулся на следующую проблему:
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
class TestClass
{
public:
~TestClass();
};
TestClass::~TestClass()
{
fstream f;
}
TestClass test;
int _tmain(int argc, _TCHAR* argv[])
{
Sleep(10000);
}
Это простой пример, чтобы вы могли воспроизвести мою ошибку. Все работает нормально, пока я не закрою окно консоли вручную (нажав X в углу консоли) во время сна. Исключение доступа.
fstream f;
строка в деструкторе. Есть ли способ использовать fstream после закрытия ручной консоли? Или я делаю что-то совершенно не так?
UPD:
Стек выглядит следующим образом:
msvcp120d.dll!std::ctype<char>::widen(char _Byte) Line 2418
msvcp120d.dll!std::basic_ios<char,std::char_traits<char> >::widen(char _Byte) Line 129
msvcp120d.dll!std::basic_ios<char,std::char_traits<char> >::init(std::basic_streambuf<char,std::char_traits<char> > * _Strbuf, bool _Isstd) Line 170
msvcp120d.dll!std::basic_istream<char,std::char_traits<char> >::basic_istream<char,std::char_traits<char> >(std::basic_streambuf<char,std::char_traits<char> > * _Strbuf, bool _Isstd) Line 48
msvcp120d.dll!std::basic_iostream<char,std::char_traits<char> >::basic_iostream<char,std::char_traits<char> >(std::basic_streambuf<char,std::char_traits<char> > * _Strbuf) Line 954
ConsoleApplication6.exe!std::basic_fstream<char,std::char_traits<char> >::basic_fstream<char,std::char_traits<char> >() Line 1133
ConsoleApplication6.exe!TestClass::~TestClass() Line 19
В соответствии с этой трассировкой стека проблема ios_base::init()
с вызовом конструктора fstream: ios_base::init()
инициализирует некоторую переменную с widen(' ')
, которая вызывает ctype::widen
на том, что, вероятно, является нулевым или уничтоженным объектом ctype
( возвращаемый use_facet
), что приводит к сбою при use_facet
вызвать виртуальную функцию-член.
Вывод: некоторые жизненно важные объекты в ЭЛТ уничтожаются до вашего объекта TestClass
, поэтому вы не можете использовать типы CRT в своем глобальном деструкторе.