关于不同编译器对strcpy溢出显示的相关问题
今天看了小甲鱼的c语言课程第19节,去使用devc++发现和老师的显示结果不一样,自己换了vs code之后就变一样了,请问这是为什么?#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "Original String";
char str2[] = "New String";
char str3;
strcpy(str2, str1);
strcpy(str3, "Copy Successful");
printf("str1: %s\n", str1);
printf("str2: %s\n", str2);
printf("str3: %s\n", str3);
return 0;
}
devc++:
vs code:
以及为什么vs code里的str1变成了“ring”? 没想到自己整会了,我受到jhq999回答的提醒才进行了下列猜想以及验证,这里非常感谢jhq999的回答。
引发猜想的原因是这样一副图
刚才明明还能正常显示,为什么我加了”123456”之后他就不能显示了呢?这引起我的思考,根据jhq999回答的提示以及论坛大量观看和我一样提问“strcpy”问题的帖子我决定先去学习什么是“栈”,在大概了解过后我开始进行打印地址来进行查看
E00-DF0=16,而“Original String123456\0”有22个字符,之后我试着调整一下str1和str2的顺序
我发现这就正常了,之后我发现DF0-D80=112,但是我明明str3只设定了100个字节,为什么给我开辟了112个长度,我试着将str3设定10个字节和1个字节,分别得到了开辟了16个长度以及1个长度,到此我猜想,难道devc++开辟长度是16向上取整吗?那么2和16开辟的长度应该相等,测试后确实相等都开辟了16个长度,到此我是明白了为什么srecpy长字符串复制给短字符串dev有时可以正常显示,而有时不可以了。
到此我又有一个疑问,那么现在str1空间里到底是“23456\0al String123456\0”,还是” 23456\0”呢?对齐进行sizeof得到有22个字符
所以对str1和str2进行打印时结果会是str1缺少以及str2显示完全,因为str2空间里没有\0所以会一直读取下去,而str1显示23456是开辟空间不够而导致“Origin”被“23456\0”覆盖了,而且剩下的” al String123456\0“还会再str1的空间里
本帖最后由 jhq999 于 2022-2-4 08:36 编辑
"New String'\0'"11
"Original St 11
ring"
猜测str1=str2+strlen("New String")+1=str2+10+1=str2+11; jhq999 发表于 2022-2-4 08:24
猜测str1=str2+strlen(str2)+1=str2+10+1=11;"
额,不好意思我有些看不懂,能详细解释一下吗? rewriteplus 发表于 2022-2-4 08:34
额,不好意思我有些看不懂,能详细解释一下吗?
分配内存时str1紧挨着str2 jhq999 发表于 2022-2-4 08:24
"New String'\0'"11
"Original St 11
嗯,我看懂了,但是这样那为什么str2显示了完整的“Original String”,不应该是str1复制给str2吗,那么str1应该不变吧,str2才应该显示不正常吧? 本帖最后由 jhq999 于 2022-2-4 16:25 编辑
rewriteplus 发表于 2022-2-4 08:41
嗯,我看懂了,但是这样那为什么str2显示了完整的“Original String”,不应该是str1复制给str2吗,那么s ...
刚开始分配时str2只有11个字节空间,紧随后面是str1,strcpy时,str1被str2覆盖了,也就是常说的str2越界了,str1里面被覆盖了5个字节
strcpy原型函数就是从源一个字节一个字节的复制到目标
页:
[1]