gets函数的一个奇怪有关问题
gets函数的一个奇怪问题#include stdio.h#include string.hvoid main(){char str1[10] For test!
gets函数的一个奇怪问题
#include <stdio.h>
#include <string.h>
void main()
{
char str1[10] = "For test!";
char str2[20];
gets(str2);
printf("str1:%s\n", str1);
printf("str2:%s\n", str2);
}
在vc6.0下运行, 如果在str2上输入多于20个字符串,,,会出现奇怪的现象!!!!他把str1的字符串给覆盖掉了,求解释。。。。。。。。。
[解决办法]
超过20字符就溢出,多出来的字符将被写入到堆栈中,这就覆盖了堆栈原先的内容,破坏一个或多个不相关变量的值。
超过20字符的时候,会改变str1的内容,这说明了两个数组是连续存放的吧,至于是这样定义的时候就会呢,还是偶然就不太清楚了
[解决办法]
这些个函数都不怎么敢用
[解决办法]
#include <stdio.h>
#include <string.h>
int main()
{
char str1[10] = "For test!";
char str2[10] = "FUCK";
char str3[10];
gets(str3);
printf("str1:%s\n", str1);
printf("str2:%s\n", str2);
printf("str3:%s\n", str3);
return 0;
}
输入超过20个字符你会发现三个数组都会改变 所以可以这样定义的话 内存是连续分配的 所以当溢出的时候,会影响到其他数组
[解决办法]
而且你在数组中间在定义上类似 int i = 1;之类的 还是会有一样的效果,所以猜测数组的集中在一块内存额
[解决办法]
[解决办法][解决办法]这就是溢出,当你学到fgets()时候就知道了,曾经就因为gets()的这个问题出现了蠕虫病毒
[解决办法][解决办法][解决办法][解决办法]我用dev-c++试了一下,没问题
可能在vc6.0里面编译的方法不一样吧,最好的办法就是单步调试,看看每个字符串里面到底是怎么被赋值的
结果应该会一目了然
[解决办法]楼主可以把内存拿出来看看:
我用的VS,str1先进栈,str2 和 str1 之间相差0x74 - 0x58 = 0x1C(只要声明时str1和str2的大小不变,这个差值是固定的), 即中间有28个字节是空着的,
所以,str2输入27个字符(包括最后一个'\0'一共28个)时,是刚好可以放下str1 和 str2的,两个的输出都没问题。如图:
如果str2输入28个字符(加上'\0'一共29个)时,str1 和str2 之间的空间就不够了,str2占用了str1的第一位,
所以str1的第一个字符'F'被str2最后的'\0'给占用了,此时str1的第一个字符是'\0',而'\0'表示字符串结束的标志,所以str1输出是空的。如图:
当str2输入29个字符(加上'\0'一共30个)时,str1的第二个字符'o'也被str1给占了,此时,str1的第一个字符是str2的倒数第二个字符'9',第二个字符是str2的倒数第一个字符'\0',所以str2输出 9,如图:
[解决办法]
图片好像显示不完整。。。
[解决办法]fgets(str2,20,stdin);
[解决办法][解决办法]str2 只是一个地址,printf 的 %s 看到这个地址后,就开始从内存中的这个地址不停地读字符,并且输出到屏幕,它看到字符'\0'才停止读内存,而不是看到str2的边界就停止..
str1与str2内存之间为什么差28个字节,我也不知道。。
是随机的吗?应该有个分配的规则吧。。
[解决办法]str1与str2内存之间为什么差28个字节,我也不知道。。
是随机的吗?应该有个分配的规则吧。。
这是应为内存分配是按页分配的,每种页表在初次申请的时候就会分配一个页表头,大小就是28字节,这个即使在调用MemFree结构的时候也不会被释放,主要是为了便于下次快速分配。
[解决办法]当一页用完后,跳到下页时,又会分配另一个页表头,大小28字节,这内存只有在删除该页时才会释放掉相对应的页表头,即会释放掉 从开始占用这页内存时所分配的28个字节。
[解决办法][解决办法]这个是不是学了操作系统才懂啊?