转:一个strcpy的问题(很容易做错)
2013-09-28 02:26 youxin 阅读(837) 评论(0) 编辑 收藏 举报下面的执行结果是什么?
#include<stdio.h> #include<string.h> void main() { char s[]="123456789"; char d[]="123"; strcpy(d,s); printf("d=%s,\ns=%s",d,s); }
执行结果:d=56789,
s=123456789
书上有关于这个的解答,说是因为当初分配的内存地址是连续内存的问题,
原来的是1234\0123456789\0,strcpy后变成123456789\06789\0。
分析:首先要解释一下,char s[]="123456789"; char d[]="123"; 这样定义的数组和变量存放在栈内存中。
栈内存是一个自顶向下分布的数据结构,那么越先定义的变量地址就越高,越后定义的地址就越低。
s比d定义在前,那么s得到了高地址,而d得到了相对低的地址,那么内存中的存放形式就是
d[] <- | -> s[]
'1' '2' '3' '\0' | '1' '2' '3' '4' '5' '6' '7' '8' '9' '\0'
字符串拷贝后:
'1' '2' '3' '4 ' | '5' '6' '7' '8' '9' '\0' '7' '8' '9' '\0'
中间的‘|’表示s[]的起始位置。
所以此时输出的是s的值是 '5' '6' '7' '8' '9' '\0'。
这个题目出的很好,一方面考查了栈的生长方向,另一方面考查了strcpy的具体细节。
如果
char d[]="12",
char d[]="1" 答案是什么呢?
执行结果依旧是:d=56789,
s=123456789
字符串拷贝后:
这里就考虑对齐的问题,一般来说是4位一对齐。如果超过4位,就是8位一对齐。
char s[]="123456789"; char d[]="12"; printf("%p %p %p %p",d,d+1,d+2,d+3); printf("\n%p \n",s); printf("%d\n",d[2]);
运行输出:
0012FF38 0012FF39 0012FF3A 0012FF3B
0012FF3C
0 字符串结束符
Key看到d[3]是不存的。char d="12"占了4位。
如果
char d[]="1234",
char d[]="12345"
执行结果依旧是:d=9,
s=123456789
输出:
123456789
9
看另一程序.
#include<stdio.h>
#include<string.h>
void main()
{
char d[]="123";
char s[]="123456789";
strcpy(d,s);
printf("d=%s,\ns=%s",d,s);
}
虽然可以看到正确的输出结果d=123456789,s=123456789执,但是产生运行错误!!
这是因为字符串拷贝后,越过了目标字串的实际空间,访问到了不可预知的地址了。
参考:http://www.cnblogs.com/aquariusgx/archive/2011/02/16/1956320.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2012-09-28 java Nested Classes
2012-09-28 转:总结java的interface和abstract class
2012-09-28 Swing线程之SwingUtilities.invokeLater 解释