在 Windows 上用 VC6 或者 VS 做过 C\C++ 开发的人都见过这些个有点奇怪并且还略带搞笑的字眼。
"烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫"------------未被初始化的栈内存
"屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯"----------------未被初始化的堆内存
很多初学者虽然经常遇到,但是并不知道这是什么梗。
其实 “烫” 和 “屯” 都是按照 GBK 编码显示的结果,对应的十六进制分别为 0xcccc, 0xcdcd
这是微软 C\C++ 编译器在 debug 模式下,引入的一种内存保护机制,会给特定的内存赋一个特定的初值。
具体怎么赋值,赋一个什么值呢? 我来列举一下常见的几种。
1. 0XCC
未被初始化的栈内存,会被写入 0XCC 。
例:
2. 0XCD
未被初始化的堆内存,会被写入 0XCD
例:
这里 d 的值为 0x00CA56B8, 可以看出,它指向的内存为cdcdcd...
这里 e 的值为 0x00C45468, 可以看出,它指向的内存也为cdcdcd...
3. 0XFD
堆内存的周围(前后各 4 个 Byte),会被写入 0XFD
这个区域被称为 “无人区”,写入 0XFD, 相当于是加了 Fence,用于检测数组越界。
还是前面的例子。
4. 0XDD
被销毁的堆内存,会被写入 0XDD 。
例:
除了上面的这些,还有一些特定字符会被用到,如 0XBAADFOOD, 0XABABABAB, 0XFEEEFEEE, 0XDEADBEEF 等,因为不常出现,这里就不细说了。
微软之所以这么做,除了内存保护,我想还为了调试方便,给它们一个确定的值而不是随机值,这样可以每次运行都是相同的结果。
说了这么多,只是想让大家理解编译器的行为。当然,不同的编译器,会有不同的行为,例如 gcc, 就不会给未初始化的变量赋初值,一切都是随机的。
最后,提醒大家
一定不要忘记初始化变量
new\delete, malloc\free 配套使用
delete\free 之后,要让指针为 null
警惕数组越界
避免野指针