请考虑以下代码段:
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
#include <Windows.h>
using namespace std;
class A
{
public:
~A()
{
cout << "I am about to die" << endl;
}
};
A a;
int _tmain(int argc, _TCHAR* argv[])
{
while (true)
{
cout << "Waiting for ctrlc" << endl;
Sleep(1000);
}
}
当我按下ctrl-c时,我得到一个带有以下callstack的AV:
0:001> kn
# Child-SP RetAddr Call Site
00 000000c0`dcdbf420 000007fe`9244fab9 MSVCP120D!std::locale::locale+0x2e [f:\dd\vctools\crt\crtw32\stdhpp\xlocale @ 324]
01 000000c0`dcdbf450 000007fe`92454e25 MSVCP120D!std::ios_base::getloc+0x29 [f:\dd\vctools\crt\crtw32\stdhpp\xiosbase @ 424]
*** WARNING: Unable to verify checksum for JustPlayC.exe
02 000000c0`dcdbf490 000007f7`524c33c0 MSVCP120D!std::basic_ios<char,std::char_traits<char> >::widen+0x25 [f:\dd\vctools\crt\crtw32\stdhpp\ios @ 127]
03 000000c0`dcdbf4f0 000007fe`9246570e JustPlayC!std::endl<char,std::char_traits<char> >+0x40 [c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream @ 999]
04 000000c0`dcdbf520 000007f7`524c2cb1 MSVCP120D!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x2e [f:\dd\vctools\crt\crtw32\stdhpp\ostream @ 201]
05 000000c0`dcdbf550 000007f7`524cefb1 JustPlayC!A::~A+0x41
06 000000c0`dcdbf580 000007fd`edd558c3 JustPlayC!`dynamic atexit destructor for 'a''+0x21
07 000000c0`dcdbf5b0 000007fd`edd551b3 MSVCR120D!doexit+0x133 [f:\dd\vctools\crt\crtw32\startup\crt0dat.c @ 628]
08 000000c0`dcdbf620 000007fd`edd55aeb MSVCR120D!_cexit+0x13 [f:\dd\vctools\crt\crtw32\startup\crt0dat.c @ 449]
09 000000c0`dcdbf650 000007fd`edd559c1 MSVCR120D!__CRTDLL_INIT+0x10b [f:\dd\vctools\crt\crtw32\dllstuff\crtlib.c @ 325]
0a 000000c0`dcdbf6a0 000007fe`d916ecef MSVCR120D!_CRTDLL_INIT+0x31 [f:\dd\vctools\crt\crtw32\dllstuff\crtlib.c @ 215]
0b 000000c0`dcdbf6d0 000007fe`d9180f6c ntdll!LdrpCallInitRoutine+0x3f
0c 000000c0`dcdbf720 000007fe`d9180e0c ntdll!LdrShutdownProcess+0x142
0d 000000c0`dcdbf830 000007fe`d612870f ntdll!RtlExitUserProcess+0xac
0e 000000c0`dcdbf870 000007fe`d61286e7 KERNELBASE!DefaultHandler+0xf
0f 000000c0`dcdbf8a0 000007fe`d8841842 KERNELBASE!CtrlRoutine+0x9b
10 000000c0`dcdbf990 000007fe`d9174f45 KERNEL32!BaseThreadInitThunk+0x1a [d:\win8_gdr\base\win32\client\thread.c @ 65]
11 000000c0`dcdbf9c0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
任何人都可以帮我理解发生了什么吗?看起来MSVCP语言环境在依赖于语言环境的全局变量析构函数之前未被初始化?解决这个问题的正确方法是什么?
答案 0 :(得分:0)
根据我对运行时工作方式的理解,在调用main()之前,在运行时的初始化时创建全局变量A.因此,它与底层操作系统的语言环境相关联,而不是与此实例中的应用程序本地绑定。因此,应用程序的区域设置在全局被破坏之前被丢弃。正如有人指出的,如果你想让析构函数使用应用程序的语言环境,那么最好的方法是使用ctrl-c的处理程序。但是,如果这个对象是在main中构造的,那么它将成为一个真正的运行时构造,并且不会遇到这个问题。