内存中常见异常值的解释(比如0xcccccccc0xcdcdcdcd和 0xfeeefeee 异常值 )
Posted dvlinker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存中常见异常值的解释(比如0xcccccccc0xcdcdcdcd和 0xfeeefeee 异常值 )相关的知识,希望对你有一定的参考价值。
* 0xcccccccc : Used by Microsoft's C++ debugging runtime library to mark uninitialised stack memory
* 0xcdcdcdcd : Used by Microsoft's C++ debugging runtime library to mark uninitialised heap memory
* 0xfeeefeee : Used by Microsoft's HeapFree() to mark freed heap memory
* 0xabababab : Used by Microsoft's HeapAlloc() to mark "no man's land" guard bytes after allocated heap memory
* 0xabadcafe : A startup to this value to initialize all free memory to catch errant pointers
* 0xbaadf00d : Used by Microsoft's LocalAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory
* 0xbadcab1e : Error Code returned to the Microsoft eVC debugger when connection is severed to the debugger
* 0xbeefcace : Used by Microsoft .NET as a magic number in resource files
平时我们只需要了解上面常见的三种就可以了:0xcccccccc、0xcdcdcdcd和 0xfeeefeee ,以帮我们迅速地发现问题并分析问题。
对于0xcccccccc和0xcdcdcdcd,在 debug 模式下,VS会把未初始化的栈内存全部填充成0xcccccccc,当成字符串看就是“烫烫烫烫……”;VS会把未初始化的堆内存全部填充成 0xcdcdcdcd,当成字符串看就是 “屯屯屯屯……”。这两类特殊的字符串,很多人应该都见到过。
那么调试器为什么要这么做呢?VS在debug下把未初始化的内存自动填充成0xcccccccc 或0xcdcdcdcd,而不是就让取随机值,是为了方便我们快速识别出问题,如果内存中出现这两个值,很可能就是因为变量没有初始化导致的。如果内存中的值是随机的,那么每次调试程序时就可能出现不一样的结果,比如这次程序崩掉,下次却能正常运行,这样显然对我们解bug是非常不利的。
如果在debug调试时遇到有变量的值为0xcccccccc 或0xcdcdcdcd,一般是变量没有初始化引起的。没有初始化的栈变量(在栈上分配内存的变量)的内存会被初始化为0xcccccccc ,没有初始化的堆变量(在堆上分配内存的变量)的内存会被初始化为0xcdcdcdcd。
对于0xfeeefeee,是用来标记堆上已经释放掉的内存,即已经释放的堆内存会被填充成0xfeeefeee。注意,如果指针指向的内存被释放了,指针变量本身的地址是没做改动的,还是之前指向的内存的地址,只是指向的堆内存会被填充成0xfeeefeee。如果该指针是一个类的成员变量,并且该类对象是在堆上分配内存的,则该类对象的堆内存被释放后(对于C++类,通常是执行delete操作),类对象中的指针变量就会被赋值为0xfeeefeee。
如果在调试代码过程中,发现指针的值为0xfeeefeee,就说明该指针所在类对象的内存被释放掉了,如果继续使用该指针变量,可能就会出问题了。我们在日常调试时会经常遇到0xfeeefeee这个异常值的。
关于VC 中 debug和Release模式下的变量初始值问题
大家应该都遇到过,程序在debug下和release下运行效果可能是不一样的,这与两个模式下的变量初始化有直接的关系。对于未人为初始化的变量,debug下会将栈内存填充成0xcccccccc,会把堆内存填充成0xcdcdcdcd,即debug下会被自动初始化;但release下变量不会被初始化,变量的值会是随机的,是分配内存时内存中“残留的值”!
如果你的程序中的某个变量没被初始化就被引用,就很有可能出现异常:
1)用作控制变量将导致流程导向不一致;
2)用作数组下标将会使程序崩溃;
3)更加可能是造成其他变量的不准确而引起其他的错误。
所以在声明变量后马上对其初始化一个默认的值是最简单有效的办法,否则项目大了就很难定位问题了。
以上是关于内存中常见异常值的解释(比如0xcccccccc0xcdcdcdcd和 0xfeeefeee 异常值 )的主要内容,如果未能解决你的问题,请参考以下文章