malloc()函数与free()函数的使用

 引入

我们知道,所有的程序都要预够的留足内存才能让程序正常的运行。在之前的学习中,在确定下一种储存的类别后,会根据已经制定好的内存管理规则选择其作用域和储存期,比如语句:

int a[10];

这个语句声明预留了10个内存位置,每一个位置都用于储存int类型的值。假如我们不输入数组的长度,编译器就会报错。但是在一些情况下,我们并不知道数组的实际长度。或者说在数据量比较大时(如a[666]),声明后就将内存安排好了,但是在最后实际没有用到那么多,就造成了内存的浪费。所以需要有一种方法,可以做到更灵活地分配内存的使用。

malloc()的使用

malloc()函数,这个函数接受一个参数----所需要的内存字节数,使用malloc()可以找到内存中闲置区域,按需分配,根据这样的特性,我们就可以将其等价为动态数组a[n]来使用。(C99之前,是不允许n为一个变量)其格式如下:

a=(*int)malloc(number*sizeof(int);

number是一个实参,用来表示想要要输入的某种类型的值(由前面定义)的个数,并且和sizeof()进行乘法运算,malloc()括号里面的全体代表你想要获取的内存字节数。注意,malloc返回值类型为void*,所以要让其成为其他类型,就需要在前面进行强制类型转换(这里是转换为int*型(int*)),知道这些,那么就可以有这样的使用:

#include<stdio.h>
#include<stdlib.h>//也可以是#include<malloc.h>
int main()
{int number
int *a;
int i;
printf("输入数量:");
scanf("%d",&number);
a=(int*)malloc(number*sizeof(int));
for(i=0;i<number;i++)
{scanf("%d",&a[i];}
return 0;}

再注意的是,使用malloc()时,要注意添加头文件,#include<stdlib.h>或者#include<malloc.h>,前者较之后者的涵盖范围更大,可以调用更多的函数。

但是,这个代码仍然有缺陷。安排了一片内存后,如果没有一个指令让其释放,那么空间内总是存在一片地址被占用,长期如此,运行内存就会逐渐下降。这样的问题叫做内存泄漏,比如:

...
int main()
{
double a[666];
int i;
...
for(i=0;i<666;i++)
b(a,666);
}
void b(double a[], int n)
{ double *temp=(double*)malloc(n*8);
...
}

在调用定义好的函数b()的时候,创建了指针temp,并且调用malloc()分配了666*8个字节的内存。当函数结束后,自动变量*temp就销毁了,但是其指向的字节仍然占用,而且因为指针的销毁,就无法访问这片内存。这片代码还有循环语句,再一次执行循环体时,又会创建*temp,又调用另一片字节数为666*8的内存,又一次无法在被使用的内存,这样的指令执行666次,或者在执行之前内存用尽,造成难以处理的问题。所以在这个时候就需要用到free()函数了。

free()函数的使用

free()函数的参数是之前malloc返回的地址,用于释放之前malloc分配的内存。就如上面的代码,在return 0;的上方加上free(a);就可以将内存归还给内存池中,也是为下一次使用这些内存做准备。注意,要使用free()时也需要有头文件#include<stdlib.h>

一些情况

如果空间用完了,用malloc()函数和free()函数会发生什么?

可以用代码来验证一下(将100兆的空间给p)

#include<stdio.h>
#include<stdlib.h>
int main()
{void *p;int i=0;
while(p=malloc(100*1024*1024))
i++;
printf("%d",i);
return 0;
}

运行结果为 0或NULL;并且会告知你申请内存失败,free()就更谈不上了。

使用free()函数的误区 

先看下面两段代码:

#include<stdio.h>
#inlcude<stdlib.h>
int main()
{
int i,n=0;
void *p;
p=&i;
free(p);
}
#include<stdio.h>
#inlcude<stdlib.h>
int main()
{
void *p;
p=malloc(666);'
p++;
free(p);
return 0;
}

在运行后,系统都会有同一个反应pointer being freed was not allocated.

即我们需要释放的指针没被分配(不是申请来的)。

第一个代码的错误在于p不是由malloc()来的,不能使用free()。

第二个代码是进行了p++,地址发生变化。

所以说,系统会记住你的申请,在使用时要原封不动地归还。

总结

1.malloc()函数可以实现和动态数组等价的效果。

2.free()函数可以将malloc()函数申请来的空间释放。

3.malloc()函数常常和free()函数一起使用。

4.使用free时要注意地址的变动。

上一篇:javascript undefined 和void0


下一篇:db2服务器linux的cache过高原因