一个简单程序引发的思考。。。。。。。about malloc
程序如下:
#include <stdio.h>
int main()
{
char *p;
p=malloc(1);
fgets(p,10,stdin);
printf( "hello: %s ", p);
}
输入:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
输出:hello: aaaaaaaaa
这明显是溢出,但我想问的是这代表了什么?C编译器的位数还是什么?
还有我不太明白的是p=malloc(1)分配的内存地址是1位,由于对齐问题也应该是分配了8个或16个字节啊,为什么输出会是9个a?
我操作系统是linux AS 4.4, glibc-2.3.4-2.36
欢迎各位来讨论。
[解决办法]
p=malloc(1); -- 这个应该p=(char *)malloc(1); 这样写吧。
你分配了一位,你输入的字符串就存到了后面的内存中,而且把后面内存中原有的数据清空。
打印时,因为你要得到10位,最后一位是\0,所以你得到了9个a。
你不妨把字符指针换成整型指针试试。
[解决办法]
首先malloc返回的是一个void*类型的指针,你却直接将它赋值给了char*。
其次,你调用了fgets()函数,而且还指定了一个10做实参,当然会输出的是9个a了!你将那个
10改为5,就会输出4个a了。至于什么原因,就不用我说了吧,嘿嘿,去查查fgets()的函数介绍
就明白了
PS:没有经过类型转换直接赋值给p,你的编译器竟然通过了?我真的不相信啊!
[解决办法]
C 本来就可以把 void* 赋给任意指针类型, 编译当然能通过...
越界了发生啥事情本来就没有定义, 啥事情都可能发生,最多free时GP下...
看不出来有啥环境下结果有可能不是这样子的...
[解决办法]
通常的C编译器是不检测下标越界的错误的,所以你输入的时候尽管理论上你自己知道是越界了,但是系统并不知道,结果就仍然认为可以操作,理论上来说这个操作后面可以实际修改很多的内存空间,这是C不安全,或者说能力较强的一个方面.要庆幸你使用的是目前的操作系统有不同的模式,有分段的机制,所以你没有改到内核,不然就可能造成其他的破坏了!