free的用法
在C语言中,free的作用是将已经使用的内存释放,一般和malloc
或calloc
配套使用, 如下例子:
int *a = (int *)malloc(sizeof(int));
*a = 100;
free(a);
a = NULL; // 重置指针
使用malloc
向操作系统申请了内存,如果不使用了,但是一直没有释放,最后将会造成内存举出, 造成程序崩溃
在上面的例子中, 我们在最后写了一行代码 a = NULL
, 是因为在C语言中,使用free
释放了内存,代表着操作系统可以重新使用这块内存, 将这块内存重新分配给其他程序, 但是在没有程序使用这块内存时,该内存中存储的数据不一定会改变
free
只是释放内存, 但是我们的指针依然指向这块内存地址, 此时依然可以读取到数据, 但是这往往意味着危险, 因为这块内存已经不属于你,读取可能没有关系, 但是往里面写数据就可能会产生未知的影响, 所以我们在代码最后将指针a
指向NULL
, 以规避误使用造成的风险。
代码测试
对于上面所说的问题,下面我们使用代码试验一下
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a;
a = (int *)malloc(sizeof(int));
*a = 1;
printf("a的内存地址是:%p, a的值是:%d\n", a, *a);
free(a);
printf("a的内存地址是:%p, a的值是:%d\n", a, *a);
return 0;
}
在上面的代码中, 我们定义了一个int指针a, 并为它分配了内存, 在下面我们使用free释放了内存, 此时我们再打印a的地址和值, 结果会是什么呢,看下面
结果:
$ gcc ./free.c && ./a.out
a的内存地址是:0x7fcb5b401780, a的值是:1
a的内存地址是:0x7fcb5b401780, a的值是:1
可以看到, 指针a依然指向原来的地址,并且可以取到值,是因为free
的作用是释放内存, 但是并不会删除我们的指针,为了防止误使用,所以可以在free
后将指针指向NULL
对free
来说, 如果参数为NULL
, 那么多次调用不会有问题, 如下代码:
// 例1:
free(NULL);
free(NULL);
free(NULL);
// 例2:
int *a = (int *)malloc(sizeof(int));
*a = 100;
free(a);
a = NULL;
free(a);
free(a);
但是, 如果一个指针被free了多次, 并且这个指针没有变化, 那么就会出错, 如下代码:
int *a = (int *)malloc(sizeof(int));
a = 100;
free(a);
// ....
free(a);
上面这段代码在编译时将会报出如下错误
a.out(13522,0x105ad5dc0) malloc: *** error for object 0x7fb35cc01780: pointer being freed was not allocated
a.out(13522,0x105ad5dc0) malloc: *** set a breakpoint in malloc_error_break to debug