|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 人之初 于 2017-7-27 16:46 编辑
废话不多说,先上原代码!
[code]#include <stdio.h>
int main()
{
char a=0,b=0; // 声明两个字符型变量并初始化为0
int *ptr=(int *)&b; //将b的地址给ptr,这里用int *强制转换
*ptr=258; //将258赋值给*ptr,也就是字符变量b
printf("a=%d,b=%d\n",a,b); //输出a和b的值。
return 0;
}
输出的结果值是:a=1,b=2.
可能很多朋友会认为输出的结果令人匪夷所思,那么接下来我帮大家分析一下吧,正好检验我学的怎么样!
1.首先,a和b是两个初始化过的字符型局部变量,在内存中他们两个的地址是相连的而且a的地址比b的地址大,所以有&a-&b=1字节(个人觉得相连是因为系统知道他的空间大小,而且在一起声明的,所以系统直接进行分配,节约环保。至于a为什么比b的地址值大,这是因为局部变量是存放在栈中的,栈的发展方向是由高到低的,在39课视频中甲鱼哥给的那张《c语言的内存分布规律》图中查到,在介绍栈的时候也说过局部变量存放在栈中)。
2.ptr是指向整型的指针变量,其指向的数据类型占sizeof(int)的字节空间,我的机器上是4个字节,而b只占1个字节,当int *ptr=(int*)&b的时候,实际上是告诉我们ptr指向的是从&b开始的一个整型数据空间。
3.258的二进制形式是00000000 00000000 00000001 00000010 二进制8位代表一字节,内存中数据的存放是由低位到高位的(以前的课程中也讲到过)所以,ptr中存放的地址实际上是00000010的地址,而prt=&b;所以效果等同于将258存放到由&b开始的4个字节大小的空间中去,这样一来,数据便覆盖了&b+1,&b+2,&b+3这三个字节空间的数据,而&a-&b=1字节,所以变量a的内容被覆盖变成00000001,十进制就是1,而此时的b是00000010,也就是十进制的2.所以才会出现最终的输出结果a=1,b=2。
简单来讲就是数据溢出覆盖了变量a造成的。
这个例题考察我们对以下几点的掌握:
1.变量在内存中分布规律
2.数据在内存中的存储(由低到高)
3.数据溢出
文中如果出现什么不足或者错误,希望大家积极帮我指出,共同学习!!!
一切超越都源自于模仿
|
评分
-
查看全部评分
|