char *c = (char*)malloc(0);
scanf("%s",c);
printf("%s",c);
---------------------------------
input:
1234567
output:
1234567
----------------------------------
我只申请了尺寸为0的内存空间,却写入了7个字符,是不是已经修改到了不该修改的内存
应该怎样合理使用malloc()函数?
感谢各位的耐心解答,谢谢!
这个问题首先得从堆栈说起,一个程序一般分为三段:代码段,数据段(静态数据),和堆栈段。堆栈段存储程序中的变量、程序传递的参数等(动态分配的变量存储在堆中,静态分配的存储在栈中)。堆栈的增长方式如下:
程序在运行的时候会预先分配堆栈空间,所以你的问题中不一定修改了不该修改的地方,有可能那里本来就是空的。
再回到malloc这个函数上来,malloc主要负责分配空间,返回该空间的首地址。那为什么申请空间为0,却可以存储7个字符呢?那是因为C语言的指针中并不检查数组的越界问题,不信的话,你可以这样:char ch[5],然后你去读写ch[6](printf或scanf),这样是不会报错的。但是我们在使用的时候,千万别越界使用,因为这样的程序是非常危险的,试想,如果越界使用的地址正好是一个操作系统的地址,那么你一修改,系统就崩了。同时,C语言的这个机制被黑客广泛地应用与缓冲区溢出攻击,所以你非但不能越界使用指针,还得时刻考虑到指针(数组)是否越界,以加强程序的安全性。
希望对你有所帮助。。。
追问一般怎么来防止越界的问题呢?比如我这里使用 scanf()函数,写代码的时候我不知道运行的时候用户会输入多少字符..
感谢用心~
这个比较简单的方法就是用一个缓冲数组,然后对这个数组进行检测。这个在安全编程中经常用,但是程序效率会有所降低。
比如:char str[100],tmpstr[100]。然后输入到tmpstr中,经检测是否越界后,再赋值给str,这样就可以避免直接使用地址,在对str读写时不会出错。
当然,话又说回来,在刚学习的阶段不用考虑这些问题,否则程序的复杂程度会大大增加,不利于学习,但是在做项目时要有这个意识。
可是... 使用scanf(),我怎么能知道程序运行的时候,用户会输入多少字符?那这时应该怎样确定分配多大内存?
追答这个在应用程序设计时会限制用户输入的有效数据的长度的!
在真正的程序设计时,我们很少会用scanf()函数来进行数据输入,会采用相应的有效代码(因开发系统情况而异) malloc函数只是动态分配内存的一个命令,学者只需要知道它的用法就好了,具体情况要具体分析进而确定程序实现方式。
你何必纠结一定要分配用户输入字符数量长度的空间呢?开一个足够大的数组不就得了?
如果你一定要malloc准确的大小,你可以
char *c;