Andy-He 发表于 2022-12-2 16:02:04

strcpy



str2按理来说是装不下str1的,结果不但能装下打印出来的长度还比原本的大小要大是怎么回事?

zhangjinxuan 发表于 2022-12-2 16:07:48

str2的大小就是5,这个是不能改变的

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

因为strcpy复制后面会贴心添加'\0',所以这个字符串的长度就是9

zhangjinxuan 发表于 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

这可能就是编译器的迷惑性为吧

Andy-He 发表于 2022-12-2 16:23:30

zhangjinxuan 发表于 2022-12-2 16:07
str2的大小就是5,这个是不能改变的

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

那str2的大小是5显然是装不下str1的,那它是怎么将str1拷贝进来的?

zhangjinxuan 发表于 2022-12-2 16:38:47

Andy-He 发表于 2022-12-2 16:23
那str2的大小是5显然是装不下str1的,那它是怎么将str1拷贝进来的?

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

Andy-He 发表于 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)

zhangjinxuan 发表于 2022-12-2 16:46:56

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

是的,但是strcpy并没有改变str2的长度,只是数组溢出了而已,但是因为str1不长,所以没有引发错误,你可以尝试把str1的内容改成更长一点的字符串,这样就会引发段错误

Andy-He 发表于 2022-12-2 17:28:42

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

C:\Users\Administrator\Desktop\all file\C语言
够长不,怎么没报错

Andy-He 发表于 2022-12-2 17:29:55

Andy-He 发表于 2022-12-2 17:28
够长不,怎么没报错

zhangjinxuan 发表于 2022-12-2 17:30:39

Andy-He 发表于 2022-12-2 17:28
够长不,怎么没报错

再长一点,可能是你运气好

zhangjinxuan 发表于 2022-12-2 17:31:32

Andy-He 发表于 2022-12-2 17:29


但是我们关心的不是这个,我们为什么要刻意溢出呢?

zhangjinxuan 发表于 2022-12-2 17:35:06

你主要的问题不是怎么才能溢出,而是strcpy为什么能复制过去,以及它的工作原理是什么,而且研究怎么溢出没有任何意义

现在你明白了吗?没有疑惑了就可以设置最佳答案了

zhangjinxuan 发表于 2022-12-2 17:38:50

Andy-He 发表于 2022-12-2 17:28
够长不,怎么没报错

另外,scanf遇到空格就停止读入,所以实际上就只读入了C:\Users\Administrator\Desktop\all

zhangjinxuan 发表于 2022-12-2 17:40:26

好的,除了研究如何溢出,现在还有什么疑惑吗

Andy-He 发表于 2022-12-2 18:05:52

zhangjinxuan 发表于 2022-12-2 17:40
好的,除了研究如何溢出,现在还有什么疑惑吗

那既然数组越界也不会报错,是不是就可以不用在意字符长度大小,直接调用了?

zhangjinxuan 发表于 2022-12-2 19:48:58

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

还是有隐患的,没事别这样搞,因为表面上可能没有什么灾害,这样可能会莫名其妙的修改默写变量,可能是与程序相关的变量,这样会导致程序运行效果不对,如果是系统变量,那就会报错
页: [1]
查看完整版本: strcpy