c语言malloc作用,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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值