I stumbled upon the following problem:
#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);
}
This is a simple example so that you can reproduce my error. Everything works fine until I close console window manually (by pressing X in the console corner) while Sleep. Access Violation Exception is thrown at the
fstream f;
line in destructor. Is there any way to use fstream after manual console closing? Or i'm doing something totally wrong?
UPD:
Stack looks like this:
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
According to this stack trace, the problem is indeed from a call from fstream's constructor: ios_base::init()
initializes some variable with widen(' ')
, which calls ctype::widen
on what is probably a null or destroyed ctype
object (returned by use_facet
), which causes a crash when it tries to call a virtual member function.
Conclusion: some vital objects in the CRT are destroyed before your TestClass
object is, therefore you can't use CRT types in your global destructor.