读书人

地址越界有关问题

发布时间: 2012-10-20 14:12:48 作者: rapoo

地址越界问题
请问下面的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$


[解决办法]
栈是由高地址向低地址增长,你第一次越界strcpy(a, p)时破坏了栈里的数据,而a下面就是指针p,也就是说把指针p的值改了,所以后面的strcpy的内容都是不可预测的,而且可能还会崩溃。所以说strcpy是不安全的,不要用。如果还不明白,你自己画一下栈就知道了
[解决办法]
程序初始化时,p指向 字符串“123456789”,
在执行第一个strcpy时, p指向的地址由指向“123456789”改为指向了值为0起始的位置, 所以以后的使用P的语句“不再输出”了。

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

Assembly code
;如下栈寄存器EBP的值为ebpchar *p = "123456789"; mov         dword ptr [ebp-4],offset string "123456789" (00431098) ; char *p ="123456789", p的值为0x431098, p的地址为0x0012ff7C00401273   lea         eax,0x0012ff74     ;a的地址, 我将地址替换了[ebp-0Ch], 方便看004012A6   lea         ecx,0x0012ff6c     ;b的地址, 我用地址替换了[ebp-14h];好了,交代完场景,strcpy来了。;strcpy从0x12ff74开始,复制了10个字节(包含0),strcpy完之后,‘\0’ 的位置是在12FF7D。;此时,注意看,p变量的首地址已经被覆盖了,被覆盖了2字节。哈哈,以后的东西不写了。好累的。
[解决办法]
探讨

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

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

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

读书人网 >C++

热点推荐