鱼C论坛

 找回密码
 立即注册
查看: 2885|回复: 15

[已解决]strcpy

[复制链接]
发表于 2022-12-2 16:02:04 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
捕获.PNG
捕获2.PNG
str2按理来说是装不下str1的,结果不但能装下打印出来的长度还比原本的大小要大是怎么回事?
最佳答案
2022-12-2 16:38:47
Andy-He 发表于 2022-12-2 16:23
那str2的大小是5显然是装不下str1的,那它是怎么将str1拷贝进来的?

因为C语言很多函数都不会对数组边界做检查,所以strcpy就不会检查能不能装得下,就只能一脸茫然地把str1强制拷贝在了str2中,多出来的字符就把str2之外的数据给覆盖了,成了这个字符串的内容,这种情况是很危险的,str1长一点就会引发段错误,不过不用担心,只要不是在搞工程,这种现象一般没有什么大问题,如果你要避免这种问题,可以使用 strncpy,可以限制拷贝长度,书上讲了的,自己可以去看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-12-2 16:07:48 | 显示全部楼层
str2的大小就是5,这个是不能改变的

但一个字符串的长度并不是直接就去看他的大小,而是从前往后找,找到第一个 '\0' 的位置,例如 "Fishc\0Com" 你strlen出来是5

因为strcpy复制后面会贴心添加'\0',所以这个字符串的长度就是9
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-2 16:14:34 | 显示全部楼层
strcpy前str2的值:
? ? ? ? ?
? 表示值未知
strcpy后str2的值:
F i s h c
但是str2 的后面还有东西,因为空间不够,后面其实还有:
F i s h c . c o m '\0'
注,strcpy会自动追加 '0\'

不过在 sizeof 眼中,这个 str2 的大小还是 5,因为str2的数组长度就是5,且为char类型

但是在 strlen 严重,这个 str2 的长度是 9, 因为 strlen 在遍历了 9 个非零字符才看到 '\0',所以 strlen 会返回 str2 的长度为 9

这可能就是编译器的迷惑性为吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-12-2 16:23:30 | 显示全部楼层
zhangjinxuan 发表于 2022-12-2 16:07
str2的大小就是5,这个是不能改变的

但一个字符串的长度并不是直接就去看他的大小,而是从前往后找,找 ...

那str2的大小是5显然是装不下str1的,那它是怎么将str1拷贝进来的?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-2 16:38:47 | 显示全部楼层    本楼为最佳答案   
Andy-He 发表于 2022-12-2 16:23
那str2的大小是5显然是装不下str1的,那它是怎么将str1拷贝进来的?

因为C语言很多函数都不会对数组边界做检查,所以strcpy就不会检查能不能装得下,就只能一脸茫然地把str1强制拷贝在了str2中,多出来的字符就把str2之外的数据给覆盖了,成了这个字符串的内容,这种情况是很危险的,str1长一点就会引发段错误,不过不用担心,只要不是在搞工程,这种现象一般没有什么大问题,如果你要避免这种问题,可以使用 strncpy,可以限制拷贝长度,书上讲了的,自己可以去看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-12-2 16:40:13 | 显示全部楼层
zhangjinxuan 发表于 2022-12-2 16:14
strcpy前str2的值:

? 表示值未知

str2的大小是5,肯定是不能完全装下str1的,但是这里str2把str1完全装下了,打印出来的和str1一样,也就是原本定义的str2大小是5,只能装5个字符,而它拷贝之后(strcpy)却装下了九个字符(FishC.com)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-2 16:46:56 | 显示全部楼层
Andy-He 发表于 2022-12-2 16:40
str2的大小是5,肯定是不能完全装下str1的,但是这里str2把str1完全装下了,打印出来的和str1一样,也就是原 ...

是的,但是strcpy并没有改变str2的长度,只是数组溢出了而已,但是因为str1不长,所以没有引发错误,你可以尝试把str1的内容改成更长一点的字符串,这样就会引发段错误
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-12-2 17:28:42 | 显示全部楼层
zhangjinxuan 发表于 2022-12-2 16:46
是的,但是strcpy并没有改变str2的长度,只是数组溢出了而已,但是因为str1不长,所以没有引发错误,你可 ...

C:\Users\Administrator\Desktop\all file\C语言
够长不,怎么没报错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-12-2 17:29:55 | 显示全部楼层
Andy-He 发表于 2022-12-2 17:28
够长不,怎么没报错

捕获3.PNG
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-2 17:30:39 | 显示全部楼层
Andy-He 发表于 2022-12-2 17:28
够长不,怎么没报错

再长一点,可能是你运气好
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-2 17:31:32 | 显示全部楼层

但是我们关心的不是这个,我们为什么要刻意溢出呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-2 17:35:06 | 显示全部楼层
你主要的问题不是怎么才能溢出,而是strcpy为什么能复制过去,以及它的工作原理是什么,而且研究怎么溢出没有任何意义

现在你明白了吗?没有疑惑了就可以设置最佳答案了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-2 17:38:50 | 显示全部楼层
Andy-He 发表于 2022-12-2 17:28
够长不,怎么没报错

另外,scanf遇到空格就停止读入,所以实际上就只读入了C:\Users\Administrator\Desktop\all
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-2 17:40:26 | 显示全部楼层
好的,除了研究如何溢出,现在还有什么疑惑吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-12-2 18:05:52 | 显示全部楼层
zhangjinxuan 发表于 2022-12-2 17:40
好的,除了研究如何溢出,现在还有什么疑惑吗

那既然数组越界也不会报错,是不是就可以不用在意字符长度大小,直接调用了?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-2 19:48:58 | 显示全部楼层
Andy-He 发表于 2022-12-2 18:05
那既然数组越界也不会报错,是不是就可以不用在意字符长度大小,直接调用了?

还是有隐患的,没事别这样搞,因为表面上可能没有什么灾害,这样可能会莫名其妙的修改默写变量,可能是与程序相关的变量,这样会导致程序运行效果不对,如果是系统变量,那就会报错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-26 09:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表