"烫烫烫屯屯屯" 那些事

"烫烫烫屯屯屯" 那些事

在 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

警惕数组越界

避免野指针





========题外话=========

附上大家关心的段子吧。



手持两把锟斤拷, (GBK与UTF-8)

口中疾呼烫烫烫。(VC++)

脚踏千朵屯屯屯, (VC++)

笑看万物锘锘锘。(HTML)

(注:这个段子不是我造的,来源于 刘松泉 zhidao.baidu.com/questi



我来解说一下,其实也只有 烫烫烫 屯屯屯 是微软编译器搞出来的,锟斤拷 锘锘锘 实际上是编码字符集转换问题。

你把 锟斤拷 锘锘锘 也归为微软编译器惹的祸?

微软编译器表示这个锅我不背。





关注微信公众号:红猴子

这是一个工科生涨知识的号,公众号的内容有CS\EE技术, 职场以及经验谈,知乎专栏文章会首发于我的微信公众号,希望能给迷茫和困惑中的朋友一些启发与帮助,欢迎围观

编辑于 2017-06-22

文章被以下专栏收录

    内容涵盖数学,EE,CS,以及热门前沿科学。 不装逼,不摆谱,不学究,不高冷。 不止技术,还有职场,更有人生。 (微信公众号:红猴子)