[问题] strcpy内存位址变掉

楼主: HILL33LOVE (就是爱希尔)   2015-01-26 12:23:10
最近在研究字串复制的使用(strcpy, strncpy, memcpy, snprintf)
在strcpy的case中,有两种情况下会Segmentation fault(程式码1, 2)
问题.想请问在[程式码1]为什么src的大小超过dest的大小
会让src的address变了呢? (由原本的0x8048af5到0x8040030)
而导致在strcpy的时候没事,而在印src字串时导致Segmentation fault
谢谢!!
[程式码1]
void test()
{
char dest[5] = "ABCDE";
char *src = "1234567890";
printf("Dest = %s, Address = %p\n", dest, dest);
printf("Src = %s, Address = %p\n", src, src);
strcpy(dest, src);
printf("======================================\n");
printf("[strcpy] Dest = %s, Address = %p\n", dest, dest);
printf("[strcpy] Src Address = %p\n", src);
printf("[strcpy] Src = %s\n", src);
}
[执行结果]
# ./a.out
Dest = ABCDE, Address = 0xbffa7e53
Src = 1234567890, Address = 0x8048af5
======================================
[strcpy] Dest = 1234567890, Address = 0xbffa7e53
[strcpy] Src Address = 0x8040030
Segmentation fault (core dumped)
[程式码2]
char dest[5] = "ABCDE";
char src[10] = "1234567890";
strcpy(dest, src);
[执行结果2]
因为src没有\0停下来 所以strcpy会导致复制src时会一直复制,而产生Segmentation
fault
E 5
D 4
C 3
B 2
Dest A 1
0
9
8
7
6
5
4
3
2
Src 1
[strcpy原型]
char *strcpy(char *s1, const char *s2)
{
char *s = s1;
while ((*s++ = *s2++) != 0) {
;
}
return (s1);
}
作者: Ebergies (火神)   2015-01-26 12:42:00
不要学 strcpy, strncpy, 这只会增加你写出 bug 的机率
楼主: HILL33LOVE (就是爱希尔)   2015-01-26 13:10:00
恩 现在都用snprintf 只是好奇为什么src的位置会变
作者: azureblaze (AzureBlaze)   2015-01-26 13:26:00
给你五个格子你硬要塞10个东西进去坏掉了很奇怪吗?
作者: wenyonba (射后不理很XX啊!!!!)   2015-01-26 13:32:00
有时候我也觉得过于追求这种不合法动作的原理其实没必要
作者: azureblaze (AzureBlaze)   2015-01-26 13:36:00
这类的问题如过需要问"为什么"那就不需要知道"为什么"知道不要这样胡搞就够了有能力应用这种胡搞的人不会问这个问题
作者: anyoiuo   2015-01-26 15:05:00
把src的Address(&src)印出,在思考strcpy原型程式码你就会发现*s1++会刚好修改到&src位址所存放的值目标内存比较小时会造成修改到不应更改的内存区块
作者: Bencrie   2015-01-26 17:45:00
你的 dest 要 6 个 char
作者: shadow0326 (非议)   2015-01-26 18:17:00
13戒之2
作者: TobyH4cker (Toby (我要当好人))   2015-01-26 18:48:00
overflow我也同意刻意研究这个没什么意义,因为本身就是不合法真想知道,要学的已经不是程式语言,而是资料结构,还有逆向工程,你才会知道说local variable在stack中是如何推叠的,才会知道overflow为什么会改变ptr addr所以“有能力应用这种胡搞的人不会问这个问题”。
作者: dirkc (3781615)   2015-01-26 21:08:00
我比较好奇的是为什么你的address不是4的倍数
作者: azureblaze (AzureBlaze)   2015-01-27 00:16:00
char本来就没alignment
作者: dirkc (3781615)   2015-01-27 08:01:00
src是global address除非"ABCDE"也放到global(怪?),或没贴出来的code还有什么
作者: anyoiuo   2015-01-27 10:03:00
src正确应是const char * = "1234567890";'位址大小问题是因为他不是存在Stack与Heap可以参考http://en.wikipedia.org/wiki/Data_segment
作者: dirkc (3781615)   2015-01-27 14:38:00
回楼上,dest在stack中比&src要小所以执行strcpy才会盖到src从src=8040030看来后面0030是'0'和'\0',所以&src=bffa7e5c老gcc常把先宣告的dest放在stack底层就是高位址年轻gcc容易把char[?]放在stack底层,也是高位址但是现在dest是低位址,所以我觉得有趣&"1234567890"应该是在.data,没别的原因应该不会配奇数位址

Links booklink

Contact Us: admin [ a t ] ucptt.com