C语言中free函数的使用详解

 更新时间:2017年05月21日 09:59:57   作者:青儿哥哥  
free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下

free函数是我们再写C语言程序时常用的函数,但是使用时需要注意,一不小心很肯能会引起吐核。

 注意:free函数与malloc()函数配对使用,释放malloc函数申请的动态内存。对于free(p)这句语句,如果p 是NULL 指针,那么free 对p 无论操作多少次都不会出问题。如果p 不是NULL 指针,那么free 对p连续操作两次就会导致程序运行错误。

 看一个程序

#include <stdio.h>
#include <stdlib.h>

int main()
{
  char * name = NULL;
  free(name);
  free(name);
  free(name);
  
  printf("no problem11111111\n");

  name = (char *) malloc(10);
  if(name)
  {
    printf("allocate successful\n");
  }
  else
  {
    printf("allocate failed\n");
  }

  free(name);
  free(name);
  
  printf("no problem2222222\n");

  return 0;
}

运行结果:

这个程序正好验证了上面的注意事项。

为了避免出现这个错误,自己写了一个函数:

void myfree(void ** point)
{
  if(*point != NULL)
  {
    free(*point);
    *point = NULL;
  }
}

这个函数将一级指针的地址作为菜蔬传入,这样就可以对一级指针进行操作。每次用free释放完空间,都将一级指针置为NULL,这样就避免了重复释放时程序崩溃。

将这个函数应用到刚才的程序中就是:

#include <stdio.h>
#include <stdlib.h>


void myfree(void ** point)
{
  if(*point != NULL)
  {
    free(*point);
    *point = NULL;
  }
}


int main()
{
  char * name = NULL;
  
  myfree((void**)&name);
  myfree((void**)&name);
  myfree((void**)&name);
  
  printf("no problem11111111\n");

  name = (char *) malloc(10);
  if(name)
  {
    printf("allocate successful\n");
    printf("地址为: %p\n",name);

  }
  else
  {
    printf("allocate failed\n");
  }

  myfree((void**)&name);
  myfree((void**)&name);
  
  printf("no problem2222222\n");

  return 0;
}

 可以发现程序已经没有错误。

但是还有一个问题需要处理: 每次调用myfree函数的时候都需要取一级指针的地址而且需要强制类型转换成void** ,也就是每次都要写(void**)&point,这样很麻烦。

其实我们可以用带参数的宏定义来简化代码,宏定义如下:

#define FREE(p) myfree((void **)&p)

 应用宏定义后的完整代码:

#include <stdio.h>
#include <stdlib.h>


#define FREE(p) myfree((void **)&p)


void myfree(void ** point)
{
  if(*point != NULL)
  {
    free(*point);
    *point = NULL;
  }
}


int main()
{
  char * name = NULL;
  
  FREE(name);
  FREE(name);
  FREE(name);
  
  printf("no problem11111111\n");

  name = (char *) malloc(10);
  if(name)
  {
    printf("allocate successful\n");
    printf("地址为: %p\n",name);

  }
  else
  {
    printf("allocate failed\n");
  }

  FREE(name);
  FREE(name);
  
  printf("no problem2222222\n");

  return 0;
}
 

好了今天就写到这里了,希望对你有帮助,如有不正确的地方,还请指点。多谢~~

相关文章

  • C/C++实现蛇形矩阵的示例代码

    C/C++实现蛇形矩阵的示例代码

    本文主要介绍了C/C++实现蛇形矩阵的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • C语言实现修改文本文件中特定行的实现代码

    C语言实现修改文本文件中特定行的实现代码

    最近由于项目需要实现修改文件的功能,所以,博主认真查阅了一些资料,但是,很遗憾,并没有太多的收获
    2013-06-06
  • Objective-C限制函数调用的频率详解

    Objective-C限制函数调用的频率详解

    这篇文章主要给大家介绍了关于Objective-C限制函数调用的频率的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-12-12
  • C++多线程编程简单实例

    C++多线程编程简单实例

    本文给大家分享的是C++多线程编程简单实例,由于C++本身没有多线程机制,在windows下我们使用调用SDK win32 api来实现,示例都很简单,讲解的也很详细,推荐给大家。
    2015-03-03
  • 详解C++ 中的三种继承方式

    详解C++ 中的三种继承方式

    这篇文章主要介绍了详解C++ 中的三种继承方式,帮助大家更好的理解和学习使用c++,感兴趣的朋友可以了解下
    2021-03-03
  • C++实现坦克大战小游戏EGE图形界面

    C++实现坦克大战小游戏EGE图形界面

    这篇文章主要为大家详细介绍了C++实现坦克大战小游戏EGE图形界面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • 详解C++ 多态的两种形式(静态、动态)

    详解C++ 多态的两种形式(静态、动态)

    这篇文章主要介绍了C++ 多态的两种形式,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
    2020-08-08
  • C语言实现找出二叉树中某个值的所有路径的方法

    C语言实现找出二叉树中某个值的所有路径的方法

    这篇文章主要介绍了C语言实现找出二叉树中某个值的所有路径的方法,针对数据结构中二叉树的实用操作技巧,需要的朋友可以参考下
    2014-09-09
  • C++精要分析decltype的作用及用法

    C++精要分析decltype的作用及用法

    decltype是C++11新增的一个关键字,和auto的功能一样,用来在编译时期进行自动类型推导。引入decltype是因为auto并不适用于所有的自动类型推导场景,在某些特殊情况下auto用起来很不方便,甚至压根无法使用
    2022-05-05
  • c++实现简单的线程池

    c++实现简单的线程池

    本文介绍的线程池采用C++语言,在windows平台下实现。本着技术分享的精神写作本文同时公布源代码。欢迎大家指出该线程池存在的问题并对当前性能进行讨论。
    2015-03-03

最新评论