malloc和free函数使用注意事项,C语言malloc和free使用详解
在 C 语言中,程序中 malloc 等内存分配函数的使用次数一定要和 free 相等,并一一配对使用。绝对要避免“malloc 两次 free 一次”或者“malloc 一次 free 两次”等情况。这就像我们的婚姻制度,必须是“一夫一妻制”,不能够“多夫一妻”或者“一夫多妻”,这些都是不合法的,如下面的示例代码所示:
#define MAX_BUF_SIZE 100
int main(void)
/*内存释放标志*/
int flag = 0;
char * p = (char *)malloc(MAX_BUF_SIZE);
if (p == NULL)
/*...*/
if (flag == 0)
free(p);
free(p);
return 0;
在上面示例代码中,当条件“if(flag==0)”成立时,“free(p)”将被执行两次,从而导致内存的双重释放错误。因此,应该消除这种双重释放潜在的风险,保证动态内存只被释放一次,如下面的示例代码所示:
#define MAX_BUF_SIZE 100
int main(void)
/*内存释放标志*/
int flag = 0;
char * p = (char *)malloc(MAX_BUF_SIZE);
if (p == NULL)
/*...*/
if (flag == 0)
/*...*/
free(p);
p=NULL;
return 0;
当然,也可以采用下面的方式:
#define MAX_BUF_SIZE 100
int main(void)
/*内存释放标志*/
int flag = 0;
char * p = (char *)malloc(MAX_BUF_SIZE);
if (p == NULL)
/*...*/
if (flag == 0)
free(p);
p = NULL;
if (p != NULL)
free(p);
p = NULL;
return 0;
除此之外,对于内存释放还必须保证只释放动态分配的内存,即不能用 free 来释放非 malloc、realloc、calloc 与 aligned_alloc 等内存分配函数分配的内存空间。与此同时,也不要将指针变量进行自增或者自减操作,使其指向动态分配的内存空间中间的某个位置,然后直接释放,这样也有可能引起未知的错误。
在 free 之后必须为指针赋一个新值
在使用指针进行动态内存分配操作时,在指针 p 被 free 释放之后,指针变量本身并没有被删除。如果这时候没有将指针 p 置为 NULL,会让人误以为 p 是个合法的指针而在以后的程序中错误使用它。
如下面的示例代码所示:
#define MAX_BUF_SIZE 100
int main(void)
char * p = NULL;
p=(char *)malloc(MAX_BUF_SIZE);
if (p == NULL)
/*...*/
/*内存初始化*/
memset(p, '\0', MAX_BUF_SIZE);
strcpy(p, "hello");
/*释放内存*/
if (p != NULL)
free(p);
if (p != NULL)
/*发生错误*/
strcpy(p, "world");
return 0;
在上面的示例代码中,第一个判断语句:
/*释放内存*/
if (p != NULL)
free(p);
虽然释放了指针变量 p,但这个时候指针变量 p 本身并没有被删除,其保存的地址并没有改变。但是,此时 p 虽不是 NULL 指针,但它却不指向合法的内存块,成为“
野指针
”或称为“
悬垂指针
”。接下来,在执行第二个判断语句时:
if (p != NULL)
/*发生错误*/
strcpy(p, "world");
条件“if (p != NULL)”成立,“strcpy(p, "world");}”语句将被继续执行,导致程序出错。或许有人会问,“free(p)”到底释放了什么?
“free(p)”释放的是指针变量 p 所指向的内存,而不是指针变量 p 本身。指针变量 p 并没有被释放,仍然指向原来的存储空间。
其实,指针只是一个变量,只有程序结束时才被销毁。释放内存空间后,原来指向这块空间的指针还是存在的,只不过现在指针指向的这块内存是不合法的。因此,在释放内存后,必须把指针指向 NULL,以防止指针在后面不小心又被解引用了。
如下面的示例代码所示:
#define MAX_BUF_SIZE 100
int main(void)
char * p = NULL;
/*内存申请*/
p = (char *)malloc(MAX_BUF_SIZE);
if (p == NULL)
/*...*/
/*内存初始化*/
memset(p, '\0', MAX_BUF_SIZE);
strcpy(p, "hello");
/*释放内存*/
if (p != NULL)
free(p);
/*在free之后给指针存储一个新值*/
p = NULL;
if (p != NULL)
/*发生错误*/
strcpy(p, "world");
return 0;
现在,通过语句“p=NULL”给指针变量 p 赋予一个 NULL 值之后,第二个条件语句“if(p!=NULL)”将不成立,语句“strcpy(p,"world")”也将不会被执行。所以一定要记住一条:free(p) 完之后,一定要将指针变量 p 置为 NULL。
关注公众号「
站长严长生
」,在手机上阅读所有教程,随时随地都能学习。内含一款搜索神器,免费下载全网书籍和视频。
微信扫码关注公众号
一套完整的嵌入式开发学习路线(高薪就业版)
一套课程卖1万,TMD太贵了!
跑了3000公里,见了一位大佬
什么是函数?以及函数的定义
C++ RTTI机制下的对象内存模型(透彻)
SQL SELECT语句:选取数据
Tkinter Button按钮控件
Tkinter布局管理控件
Java到底能干什么?实事求是地说一下
Spring MVC国际化