关于缓冲区溢出的一段代码

Snailqiu 2013-09-15 09:25:16
我已经大概知道了了缓冲区溢出的原理了。有下面一段代码:
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
int i=1;
char buf[2]={'a','b'};

printf("&i is:%p\n",&i);
printf("&buf[0] is:%p\n",&buf[0]);
printf("&buf[1] is:%p\n",&buf[1]);

strcpy(buf,"xy");

printf("buf[0] is:%c\n",buf[0]);
printf("buf[1] is:%c\n",buf[1]);
printf("i is:%d\n",i);
return 0;
}运行之后,在内存中
&i is:0022FF44
&buf[0] is:0022FF42
&buf[1] is:0022FF43
buf[0]变成了x,buf[1]变成了y,字符串截断符覆盖了i,改写了i的值。
我想问的是:为什么i会变成0,这个0是怎么算出来的?

如果把strcpy(buf,"xy");改成strcpy(buf,"xyz"),输出结果i是122,这个122又是怎么算出来的?
我就是不知道计算方法,谁能够详细给我解释一下。
谢谢。
...全文
336 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
char buf[2]={'a','b'}; 你这里的字符数组不是字符串,没有NUL结束符 strcpy(buf,"xy");实际上是这样 buf[0] = 'x' buf[1] = 'y' buf[2] = '\0' 编译器将buf先入栈,然后再将i栈,所以i的位置就是buf[2],这样 i的值就变为了'\0'等于0 同理strcpy(buf,"xyz"), buf[0] = 'x'; buf[1] = 'y' buf[2] = 'z' buf[3] = '\0' i的内存是这样存储的(小顶端机) 0x 01 00 00 00 经过strcpy(buf,"xyz"),之后,i的存储变为了 0x 7a 00 00 00 所以i的值变为了i = 0x0000007a = 122 如果是 strcpy(buf,"xyzz")的话 i的存储变为了 0x 7a 7a 00 00 所以i的值变为了i = 0x00007a7a = 31354
赵4老师 2013-10-15
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
HappyerMano 2013-10-15
  • 打赏
  • 举报
回复
int型变量i的十六进制表示为0x00 00 00 01,但在内存中采用地位存储低地址的方式,也就是内存中从低位到高位依次存储的是01 00 00 00(十六进制表示),然后字符串截断符‘\0’,内存表示为00(十六进制表示),会覆盖掉01,然后int型变量i的在内存中就变成了00 00 00 00(32位十六进制表示),也就是0x00 00 00 00,也就是0。
奔跑的码仔 2013-09-15
  • 打赏
  • 举报
回复
同意四楼4楼,对于字符串数组,务必预留出’\0’空间,否则出现各种匪夷所思的现象
missheaven2011 2013-09-15
  • 打赏
  • 举报
回复
字符串结束符覆盖了i的值
  • 打赏
  • 举报
回复
楼上正解
图灵狗 2013-09-15
  • 打赏
  • 举报
回复
不是简单的122+122,而是第一个字节为122,第二个字节为122,而一个字节是8bits,所以: i = 122 | (122 << 8) 相当于, i = 122 + 122 * 256 = 31354
引用 3 楼 Snailqiu 的回复:
还有,如果像你所说:strcpy(buf,"xyz"); 最后两个字符z\0,把i中的1给覆盖了, z的ascii码为122,所就是变成122了, 如果我把xyz改成xyzz,那就是最后3个字符zz\0把i中的1给覆盖了,那结果就应该是122+122,可我的输出结果是31354.这是为什么。 是按照ascii码来算的吗?
Snailqiu 2013-09-15
  • 打赏
  • 举报
回复
还有,如果像你所说:strcpy(buf,"xyz"); 最后两个字符z\0,把i中的1给覆盖了, z的ascii码为122,所就是变成122了, 如果我把xyz改成xyzz,那就是最后3个字符zz\0把i中的1给覆盖了,那结果就应该是122+122,可我的输出结果是31354.这是为什么。 是按照ascii码来算的吗?
Snailqiu 2013-09-15
  • 打赏
  • 举报
回复
如果把定义中的 int i=1 改成int i=-1 为什么最后的输出结果变成了i=-256
  • 打赏
  • 举报
回复
strcpy(buf,"xy"); 最后一字符中\0,把i中的1给覆盖了,所以就成0了 strcpy(buf,"xyz"); 最后两个字符z\0,把i中的1给覆盖了, z的ascii码为122,所就是变成122了, 不知这样说,你能否懂

70,022

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧