内存中常见异常值的说明(0xcccccccc、0xcdcdcdcd、0xfeeefeee和0xdddddddd 等)

编程入门 行业动态 更新时间:2024-10-09 17:25:20

内存中常见<a href=https://www.elefans.com/category/jswz/34/1771210.html style=异常值的说明(0xcccccccc、0xcdcdcdcd、0xfeeefeee和0xdddddddd 等)"/>

内存中常见异常值的说明(0xcccccccc、0xcdcdcdcd、0xfeeefeee和0xdddddddd 等)

VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)++软件分析工具从入门到精通案例集锦(专栏文章正在更新中...)++基础与进阶(专栏文章,持续更新中...).html常见的异常值如下所示:

* 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.

* 0xddddddddUsed by MicroQuill's SmartHeap and Microsoft's C/C++ debug free() function 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.

1、常见异常值说明

        一般我们只需要了解常见的这4种异常值就可以了:0xcccccccc、0xcdcdcdcd、0xfeeefeee和0xdddddddd,这几个值的说明如上所示。我们需要提高对这几个异常值的敏感度,看到这些值就能大概知道是什么原因引起的,以这个为线索,一般我们就能迅速地分析并定位问题。

1.1、异常值0xcccccccc和0xcdcdcdcd

        对于0xcccccccc和0xcdcdcdcd,在 debug 模式下,Visual Studio会把未初始化的栈内存全部填充成0xcccccccc,当成字符串看就是“烫烫烫烫……”;Visual Studio会把未初始化的堆内存全部填充成 0xcdcdcdcd,当成字符串看就是 “屯屯屯屯……”。这两类特殊的字符串,很多人应该都见到过。

       那么调试器为什么要这么做呢?Visual Studio在debug下把未初始化的内存自动填充成0xcccccccc 或0xcdcdcdcd,而不是随机值,是为了方便我们快速识别出问题,如果内存中出现这两个值,很可能就是因为变量没有初始化导致的。如果内存中的值是随机的,那么每次调试程序时就可能出现不一样的内存值,比如这次程序崩掉,下次却能正常运行,这样显然对我们排解bug是非常不利的。

如果在debug调试时遇到有变量的值为0xcccccccc 或0xcdcdcdcd,一般是变量没有初始化引起的。没有初始化的栈变量(在栈上分配内存的变量)的内存会被初始化为0xcccccccc ,没有初始化的堆变量(在堆上分配内存的变量)的内存会被初始化为0xcdcdcdcd。

        相关项目问题排查实例,可以参见我之前写的文章:

排查软件启动时访问了0xcdcdcdcd内存地址导致内存访问违例的崩溃++程序崩溃问题的详细分析

1.2、异常值0xfeeefeee 

        对于0xfeeefeee,是Debug下用来标记堆上已经释放掉的内存,即已经释放的堆内存中会被填充成0xfeeefeee。注意,如果指针指向的内存被释放了,指针变量本身的地址是没做改变的,还是其之前指向的内存的地址,只是其指向的堆内存中被填充成0xfeeefeee。如果该指针是一个类的成员变量,并且该类对象是在堆上分配内存的,则该类对象的堆内存被释放后(对于C++类,通常是执行delete操作),类对象中的指针变量就会被赋值为0xfeeefeee。

如果在调试代码过程中,发现指针的值为0xfeeefeee,就说明该指针所在类对象的内存被释放掉了,如果继续使用该指针变量,可能就会出问题了。我们在日常调试时会经常遇到0xfeeefeee这个异常值。

       相关项目问题排查实例,可以参见我之前写的文章:

排查软件关闭时访问了0xfeeefeee内存地址导致内存访问违例的崩溃

1.3、异常值0xdddddddd 

       对于0xdddddddd,是Debug下用来标记堆上已经释放掉的内存,即已经释放的堆内存会被填充成0xdddddddd。 0xfeeefeee也是Debug下用来填充已经释放的堆内存,但0xdddddddd和0xfeeefeee的使用场景应该是有区别的,具体区别我也不太清楚,仅从上面的说明文字中没法区分。

       之前在项目问题中看到的基本都是0xfeeefeee,没见到过0xdddddddd,但前段时间在Debug下调试代码时遇到了,代码中访问了已经释放的内存,内存中都被置为0xdddddddd,这还是第一次遇到0xdddddddd异常值!正是通过0xdddddddd的说明,得知这个0xdddddddd是用来填充已经释放的堆内存,以这个为线索,快速地定位了问题!

我之前为了搞清楚这两个0xdddddddd和0xfeeefeee的区别(在何种场景下会使用),写了很多测试代码,但不幸的是,每次释放后的堆内存中都被填充成了0xfeeefeee。

       相关项目问题排查实例,可以参见我之前写的文章:

访问0xdddddddd内存地址引发软件崩溃的问题排查

2、关于VS 中 debug 和 Release 模式下的变量初始值问题

       大家应该都遇到过,Visual Studio编译出来的程序,在debug下和release下运行效果不一样的情况(表现出不同的现象),可能的原因之一,就是与两个模式下的变量初始化有直接的关系。对于未人为初始化的变量,debug下会将栈内存填充成0xcccccccc,会把堆内存填充成0xcdcdcdcd,即debug下会被自动初始化;但release下变量不会被初始化,变量的值会是随机的,是分配内存时内存中“残留的值”,所以引发了程序在debug和release下的不同表现。

        如果你的程序中的某个变量没被初始化就被访问,有可能出现如下的异常:

1)未初始化的变量用作控制变量时,可能会导致业务流程和代码走向不一致;

2)未初始化的变量用作数组下标时,会导致数组越界,引发程序崩溃;

3)未初始化的C++类指针,可能会导致内存访问违例,引发程序崩溃。

所以,我们要养成好的编码习惯,在声明变量后马上对其初始化,初始化成一个默认值,这是最简单有效的办法,否则项目大了就较难定位问题了。这点对于缺乏开发经验的新人,要特别注意。

可能有人会说,只要控制好现有的代码,不让代码去访问未初始化的变量,就没问题,不一定非要一上来就对变量进行初始化。即便是这样,也是不可取的,因为代码后面可能会交由其他人维护,每个人编码水平是有差异的,你这里可以保证没问题,到别人那边可能就会出问题。

更多推荐

内存中常见异常值的说明(0xcccccccc、0xcdcdcdcd、0xfeeefeee和0xdddddddd 等)

本文发布于:2024-02-13 07:19:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1757570.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:异常   内存   常见   xcccccccc   xfeeefeee

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!