char[]和strcat()问题

阿尔博特 2012-06-03 04:19:36

char s[] = "12345";
char str[] = "abcde";
strcat(s,str);
printf("%d\n",strlen(s));
printf("%s\n",s);
C++primer 和KR的C Programming Language 里都说s要有足够的空间,s的大小就是6。为什么输出结果是
10 12345abcde哪?
...全文
322 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
cryingbee 2012-06-04
  • 打赏
  • 举报
回复
碰巧而已,两个字符串原本都在栈里,而且是连续的:

12345\0abcde\0

被你strcat了之后
12345abcde\0\0了。
C__Allen 2012-06-04
  • 打赏
  • 举报
回复
strlen和sizeof没搞清楚
herman~~ 2012-06-04
  • 打赏
  • 举报
回复
何必这么辛苦呢,直接用两个string相加完事了
majia2011 2012-06-04
  • 打赏
  • 举报
回复
路过看热闹,忍不住感慨下

如果哪一天,我去大学教书,铁比现在老师讲的好,至少我会拿国外名校的教材,教会那些孩子,什么是计算机
赵4老师 2012-06-04
  • 打赏
  • 举报
回复
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
AnYidan 2012-06-03
  • 打赏
  • 举报
回复
c 认为你必须为自己的行为负责
MK 2012-06-03
  • 打赏
  • 举报
回复
楼上+1
liutengfeigo 2012-06-03
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

1.栈中的变量是从高地址到低地址分配的
2.变量定义之间可能会插入其他信息(如debug模式下有可能会插入调试信息)
3.strcat(s,str);即使str和s之间没有插入任何其他信息,也必定会破坏栈帧的.因为s的地址比str的地址高,strcat(s,str)后,新拼接到s后面的字符不会占用str的空间的.
4.lth还是太挫了,这么简单的问题都要本座出手
[/Quote]
本ID还小,等本ID有你这么大时,本ID就灭了你.
SammyLan 2012-06-03
  • 打赏
  • 举报
回复
1.栈中的变量是从高地址到低地址分配的
2.变量定义之间可能会插入其他信息(如debug模式下有可能会插入调试信息)
3.strcat(s,str);即使str和s之间没有插入任何其他信息,也必定会破坏栈帧的.因为s的地址比str的地址高,strcat(s,str)后,新拼接到s后面的字符不会占用str的空间的.
4.lth还是太挫了,这么简单的问题都要本座出手
liutengfeigo 2012-06-03
  • 打赏
  • 举报
回复

我是菜鸟.路过.以后在研究这玩意.
beckhanyan 2012-06-03
  • 打赏
  • 举报
回复
调试模式下不行吧。。变量两端会有调试信息的啊
jackyjkchen 2012-06-03
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
标准是说未定义吧.
但是是按照内存是按页面分配的啊.
然后虚拟地址到物理地址的时候,如果已经在缓存里了,就不会进入vm里去查.
直接缓存命中了.
所以不会引发段错误.
-----------------------------
我暂时是这么理解的.如果有错,希望楼下的大牛提出.
[/Quote]

老弟,没这么复杂……不管怎么样都是内存越界了,不是什么缓存问题,如果你下面几个字节有函数返回地址,我可以用这段代码打开个记事本……
liutengfeigo 2012-06-03
  • 打赏
  • 举报
回复
标准是说未定义吧.
但是是按照内存是按页面分配的啊.
然后虚拟地址到物理地址的时候,如果已经在缓存里了,就不会进入vm里去查.
直接缓存命中了.
所以不会引发段错误.
-----------------------------
我暂时是这么理解的.如果有错,希望楼下的大牛提出.
W170532934 2012-06-03
  • 打赏
  • 举报
回复
其实strcat函数不检查数组空间的大小的。这样用是不安全的。strcat只是把字符拷贝到s的后面,其实你已经越界了。为什么会输出,那就是数据完整的写到了数组s的后面啊,所以能输出。
jackyjkchen 2012-06-03
  • 打赏
  • 举报
回复
C语言的栈维护是程序员的事情,编译器不负责检查越界

这个程序可能正常运行,也可能崩溃,dos等没有保护模式的干死操作系统也说不定

69,374

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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