Visual C++ RunTime的特征——非烫即屯
大一刚学C语言,第二次上机课,当我发现我照着书抄写的程序在运行之外的黑框里面跳出一排“烫烫烫烫烫”,当时就震惊了。你们能想象一个来自小城, 在大学之前没有怎么接触过电脑更不懂代码的孩子当时内心的恐惧吗?我真的以为是这是电脑过热发出来的警告,于是我弯下腰把插头拔了。
——————————————————————————————
VC runtime debug version会把stack初始化成0xcc,unicode中0xcccc(双字节)就是中文的烫。如果你开了个char[],然后最后一个字符忘了 设置成0x00,然后去printf这个字符,那么整个stack从这个局部字符数组开始都输出到console,就变成了“烫烫烫烫烫”。
为啥把stack初始化成0xcc而不是0x00呢?是因为0xcc 在intel x86芯片指令集中代表int 3,也就是debug中断,该指令会自动把程序停在单步调试状态,然后去寻找系统中注册的调试器,如果找不到调试器,那么就会终止程序。这一开始是为了调 试栈缓冲溢出错误的。如果出现溢出,并且代码尝试执行缓冲中的指令,就会进入单步调试状态。
这是debug version, 那么release verion呢?发布版会把栈初始化成0xcd,这个就是imm8,就是立即中断退出的意思。这时候因为运行在用户机器上,没有调试器,也不希望用户来调试你的程序。0xcdcd就是中文的“屯”字。你会看见一些写的超烂的程序经常会出现“屯屯屯屯屯屯”。的确挺屯的,F。
在今天这个芯片DEP,操作系统NX锁定双保险的时代,这种初始化已经没有啥必要了,这个烫屯还存在纯粹是历史原因。
所以在俺们那个电脑还比较古早的年代,说人人品不好,那叫非奸即盗。说程序写的烂,那叫非烫即屯。
参考:
http://www.ccthere.com/article/4019197
——————————————————————————————
通过实测,我认为确实如上所说,所以自己必须要在构造函数中初始化。
如果没有初始化就会出事情(就会默认初始化成0xcdcdcdcd),比如在.h文件中定义:
int* m_test;
在析构函数里写上:
MyClass::~MyClass()
{
if (m_test)
delete m_test;
}
天杀的,居然会执行delete语句,然后程序报错,所以同志们要千万小心啊!!
——————————————————————————————
int xxx;
printf(" xxx = %d", xxx);
int* ddd;
printf("%d", ddd);
ddd = new int(10);
printf("%d", ddd);
上
面这段代码Debug模式下的运行结果是,xxx是一个随机值1366087313(每次运行还是固定值,估计是OS整体内存使用情况不变的缘
故),ddd的值是随机值0x00000100(每次运行还是固定值),但是m_test的值是0xcdcdcdcd,不是0xcccccccc,不知道
为什么(问题1)。
后来又运行了几个软件,这时xxx的值变成了255841937,但ddd的值仍是0x00000100(问题2)。
注:以上调试都是VS2008sp1 + Qt程序下调试。
【原文地址:http://www.cnblogs.com/findumars/p/4003800.html】