C语言 malloc()函数 分配内存空间尺寸的问题

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读写时不会出错。
当然,话又说回来,在刚学习的阶段不用考虑这些问题,否则程序的复杂程度会大大增加,不利于学习,但是在做项目时要有这个意识。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2016-01-14
C语言中malloc是动态内存分配函数。
函数原型:void *malloc(unsigned int num_bytes);
参数:num_bytes 是无符号整型,用于表示分配的字节数。
返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。void* 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者...)
功能:分配长度为num_bytes字节的内存块
注意:当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。关于该函数的原型,在以前malloc返回的是char型指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。
实例:
#include"stdio.h"

#include"malloc.h"//malloc()函数被包含在malloc.h里面

int main(void)
{

char*a=NULL;//声明一个指向a的char*类型的指针

a=(char*)malloc(100*sizeof(char));//使用malloc分配内存的首地址,然后赋值给a

if(!a)//如果malloc失败,可以得到一些log

{
perror("malloc");
return-1;
}

sprintf(a,"%s","HelloWorld\n");//"HelloWorld\n"写入a指向的地址

printf("%s\n",a);//输出用户输入的数据

free(a);//释放掉使用的内存地址

return0;

}
第2个回答  推荐于2018-02-27
malloc是给指针变量分配内存空间的函数命令
正确使用:
分配的空间要能保证容下你想存储的数据,不要和机器逗着玩(分配0空间,或少于自己实际需要的空间),如你上面的操作,表面上你程序运行没有问题,可实际上你占用了别人的地盘,只是当前你很幸运没有使程序出现问题,但不保证一定不出问题!!

不再使用的指针,一定要free()来释放空间!malloc 与free要配对使用,即:有malloc必要有free追问

可是... 使用scanf(),我怎么能知道程序运行的时候,用户会输入多少字符?那这时应该怎样确定分配多大内存?

追答

这个在应用程序设计时会限制用户输入的有效数据的长度的!
在真正的程序设计时,我们很少会用scanf()函数来进行数据输入,会采用相应的有效代码(因开发系统情况而异) malloc函数只是动态分配内存的一个命令,学者只需要知道它的用法就好了,具体情况要具体分析进而确定程序实现方式。

本回答被提问者和网友采纳
第3个回答  2013-10-04

你何必纠结一定要分配用户输入字符数量长度的空间呢?开一个足够大的数组不就得了?

如果你一定要malloc准确的大小,你可以

char *c;
char *s=malloc(100000*sizeof(char));//malloc一个足够大的数组,暂时储存输入
scanf("%s",s);
c=(char*)malloc(strlen(s)*sizeof(char));
strcpy(c,s);
free(s);//输入结束后把输入储存,再把这个大数组释放

相似回答