| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1090 人关注过本帖, 1 人收藏
标题:strcpy 输出结果求解释!多谢
只看楼主 加入收藏
ybjkl
Rank: 2
等 级:论坛游民
帖 子:86
专家分:85
注 册:2011-6-21
结帖率:95.65%
收藏(1)
已结贴  问题点数:5 回复次数:7 
strcpy 输出结果求解释!多谢
#include<stdio.h>
#include<string.h>
int main(void)
{
    char s[]="123456789";
    char d[]="123";
    strcpy(d,s);
    printf("%s,\n%s",d,s);
    return 0;
}

输出结果为
123456789
56789
搜索更多相关主题的帖子: include return 
2011-09-13 15:41
tisyang
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:132
专家分:737
注 册:2011-5-7
收藏
得分:3 
这个,strcpy 是不安全的函数,你这个输出结果跟 s 和 d 的初始内存地址有关系。在不同的编译情况下初始内存地址不同,那么你这个程序的输出就不会相同。
不相信的话,可以打印两个数组的地址。
可以试试加了优化选项的编译结果和未优化的。

C++ 用无参数构造函数生成对象时候请勿在构造函数后添加无用的那一对括号,否则有可能会被当成函数声明而忽略,嗯,栈上构建的时候就是这样。
2011-09-13 15:54
Devil_W
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:9
帖 子:1160
专家分:1797
注 册:2009-9-14
收藏
得分:2 
最开始的mem

1234\0123456789\0

strcpy之后

12345689\06789\0

在little ending的OS上会是这样的behavior.
2011-09-13 16:00
tisyang
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:132
专家分:737
注 册:2011-5-7
收藏
得分:0 
程序代码:
#include<stdio.h>
#include<string.h>
int main(void)
{
    char s[]="123456789";
    char d[]="123";
    printf("S: %X\nD: %X\n", s, d);
    strcpy(d,s);
    printf("%s,\n%s\n",d,s);
    return 0;
}

不加任何优化的输出(gcc 编译):
S: BFC5CAE6
D: BFC5CAE2
123456789,
56789

数组 s 的 地址之比 d 大4个字节,原来的数组长度分别是 s 10 bytes, d 4bytes;
strcpy(d,s) 这个函数不会检查缓冲区越界的情况,直接把 s 的内容往 d 的地址开始写。
写之前 内存排布:
1  2  3 \0  1  2  3  4  5  6  7  8  9 \0
 d           s        

strcpy 之后
1  2  3  4  5  6  7  8  9 \0  7  8  9 \0
 d           s   

那么此时 s 开始的输出就是 5 一直到 \0 了
PS: 不知道为什么可以用程序来验证的, 打印地址什么的是基础技巧了。。。。

C++ 用无参数构造函数生成对象时候请勿在构造函数后添加无用的那一对括号,否则有可能会被当成函数声明而忽略,嗯,栈上构建的时候就是这样。
2011-09-13 16:03
tisyang
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:132
专家分:737
注 册:2011-5-7
收藏
得分:0 
tisyang@debian:~/Sources/c-cpp/temp$ gcc -O2 -o strcpy strcpy.c
tisyang@debian:~/Sources/c-cpp/temp$ ./strcpy
S: BFA89152
D: BFA8915C
123456789,
123456789

这是 gcc 开启了 O2 优化选项后编译的输出结果
这个时候内存的初始排布就变化了,不会重现那样的结果。。。。。。

C++ 用无参数构造函数生成对象时候请勿在构造函数后添加无用的那一对括号,否则有可能会被当成函数声明而忽略,嗯,栈上构建的时候就是这样。
2011-09-13 16:06
ybjkl
Rank: 2
等 级:论坛游民
帖 子:86
专家分:85
注 册:2011-6-21
收藏
得分:0 
果然!谢谢啦
2011-09-13 16:06
laoyang103
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:内蒙古包头
等 级:贵宾
威 望:19
帖 子:3082
专家分:11056
注 册:2010-5-22
收藏
得分:0 
其实楼上已经解释的很详细了  补充一下

函数的调用是用堆栈来完成的  包括主函数也是这样的  函数里面的临时变量都保存在堆栈里面

因为堆栈是一种后进先出的数据结构  所以两个字符串的存储结构就如楼上的第一个图所示
1  2  3 \0  1  2  3  4  5  6  7  8  9 \0
d           s
后面的楼上都已经解释了

                                         
===========深入<----------------->浅出============
2011-09-13 16:09
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
回复 3楼 Devil_W
你现在也这么低调了~~
2011-09-13 20:58
快速回复:strcpy 输出结果求解释!多谢
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014854 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved