专业网站建设品牌,十四年专业建站经验,服务6000+客户--广州京杭网络
免费热线:400-683-0016      微信咨询  |  联系我们

malloc和free函数使用注意事项,C语言malloc和free使用详解

当前位置:网站建设 > 技术支持
资料来源:网络整理       时间:2023/2/17 11:53:39       共计:3611 浏览
在 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。
版权说明:
本网站凡注明“广州京杭 原创”的皆为本站原创文章,如需转载请注明出处!
本网转载皆注明出处,遵循行业规范,如发现作品内容版权或其它问题的,请与我们联系处理!
欢迎扫描右侧微信二维码与我们联系。
·上一条:内存泄漏的场景分析和避免方法总结,C语言内存泄漏详解 | ·下一条:feof和ferror函数,C语言feof和ferror函数详解

Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有    粤ICP备16019765号 

广州京杭网络科技有限公司 版权所有