地址越界问题

bill_liang 2012-09-27 03:27:44
请问下面的2 b, 3 a, 4 a, 5 a为什么没有输出。谢谢。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
const char *p = "123456789";
char a[5];
char b[6];

memset(a,0,sizeof(a));
strcpy(a,p);
printf("1 a:[%s],size:[%d]\n",a,sizeof(a));

memset(b,0,sizeof(b));
strcpy(b,p);
printf("2 b:[%s],size:[%d]\n",b,sizeof(b));

memset(a,'\0',sizeof(a));
strncpy(a,p,5);
printf("3 a:[%s],sizeof:[%d]\n",a,sizeof(a));

memset(a,'\0',sizeof(a));
strncpy(a,p,4);
printf("4 a:[%s],size:[%d]\n",a,sizeof(a));

memset(a,'\0',sizeof(a));
strncpy(a,p,6);
printf("5 a:[%s],size:[%d]\n",a,sizeof(a));

return 0;
}

-bash-3.2$ gcc -o 8 8.c
-bash-3.2$ ./8
1 a:[123456789],size:[5]
2 b:[],size:[6]
3 a:[],sizeof:[5]
4 a:[],size:[5]
5 a:[],size:[5]

-bash-3.2$
...全文
306 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
bill_liang 2012-09-28
  • 打赏
  • 举报
回复
谢谢各位,尤其是alan1985和TheNewIpad
TheNewIpad 2012-09-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

程序初始化时,p指向 字符串“123456789”,
在执行第一个strcpy时, p指向的地址由指向“123456789”改为指向了值为0起始的位置, 所以以后的使用P的语句“不再输出”了。

可以查看汇编代码:以VS6为例
Assembly code

;如下栈寄存器EBP的值为ebp
char *p = "123456789";
mov dword ptr [……
[/Quote]

说白了,起始就是P指向的位置已经不是“123459678”, 而是"\0........"了
TheNewIpad 2012-09-27
  • 打赏
  • 举报
回复
程序初始化时,p指向 字符串“123456789”,
在执行第一个strcpy时, p指向的地址由指向“123456789”改为指向了值为0起始的位置, 所以以后的使用P的语句“不再输出”了。

可以查看汇编代码:以VS6为例

;如下栈寄存器EBP的值为ebp
char *p = "123456789";
mov dword ptr [ebp-4],offset string "123456789" (00431098) ; char *p ="123456789", p的值为0x431098, p的地址为0x0012ff7C

00401273 lea eax,0x0012ff74 ;a的地址, 我将地址替换了[ebp-0Ch], 方便看

004012A6 lea ecx,0x0012ff6c ;b的地址, 我用地址替换了[ebp-14h]

;好了,交代完场景,strcpy来了。
;strcpy从0x12ff74开始,复制了10个字节(包含0),strcpy完之后,‘\0’ 的位置是在12FF7D。
;此时,注意看,p变量的首地址已经被覆盖了,被覆盖了2字节。哈哈,以后的东西不写了。好累的。


  • 打赏
  • 举报
回复
memset(a,0,sizeof(a));
strcpy(a,p);
//这里应该在末尾加一个'\0'
printf("1 a:[%s],size:[%d]\n",a,sizeof(a));

memset(b,0,sizeof(b));
strcpy(b,p);
//这里应该在末尾加一个'\0'
printf("2 b:[%s],size:[%d]\n",b,sizeof(b));

memset(a,'\0',sizeof(a));
strncpy(a,p,5);
//这里应该在末尾加一个'\0'
printf("3 a:[%s],sizeof:[%d]\n",a,sizeof(a));

memset(a,'\0',sizeof(a));
strncpy(a,p,4);
//这里应该在末尾加一个'\0'
printf("4 a:[%s],size:[%d]\n",a,sizeof(a));

memset(a,'\0',sizeof(a));
strncpy(a,p,6);
//这里应该在末尾加一个'\0'
mujiok2003 2012-09-27
  • 打赏
  • 举报
回复
strcpy(a,p); //越界,之后的代码都不可靠了
alan1985 2012-09-27
  • 打赏
  • 举报
回复
栈是由高地址向低地址增长,你第一次越界strcpy(a, p)时破坏了栈里的数据,而a下面就是指针p,也就是说把指针p的值改了,所以后面的strcpy的内容都是不可预测的,而且可能还会崩溃。所以说strcpy是不安全的,不要用。如果还不明白,你自己画一下栈就知道了
bill_liang 2012-09-27
  • 打赏
  • 举报
回复
请答案

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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