http://blog.163.com/huangguoqiang_123@126/blog/static/14104311420112201375274/

既然有分配,那就必须有释放。不然的话,有限的内存总会用光,而没有释放的内存却在空闲。与 malloc 对应的就是 free 函数了。

free 函数只有一个参数,就是所要释放的内存块的首地址。比如上例:free(p);

free 函数看上去挺狠的,但它到底作了什么呢?其实它就做了一件事:斩断指针变量与这块内存的关系。比如上面的例子,我们可以说 malloc 函数分配的内存块是属于 p 的,因为我们对这块内存的访问都需要通过 p 来进行。 函数就是把这块内存和 p 之间的所有关free系斩断。从此 p 和那块内存之间再无瓜葛。
至于指针变量 p 本身保存的地址并没有改变,但是它对这个地址处的那块内存却已经没有所有权了。那块被释放的内存里面保存的值也没有改变,只是再也没有办法使用了。这就是 free 函数的功能。

按照上面的分析,如果对 p 连续两次以上使用 free 函数,肯定会发生错误。因为第一使用 free 函数时,p 所属的内存已经被释放,第二次使用时已经无内存可释放了。

关于这点,我上课时让学生记住的是:一定要一夫一妻制,不然肯定出错。

malloc 两次只 free 一次会内存泄漏;malloc 一次 free 两次肯定会出错。

也就是说,在程序中 malloc 的使用次数一定要和 free 相等,否则必有错误。这种错误主要发生在循环使用malloc 函数时,往往把 malloc 和 free 次数弄错了。

注意:内存释放之后
既然使用 free 函数之后指针变量 p 本身保存的地址并没有改变,那我们就需要重新把 p的值变为 NULL:p = NULL;这个 NULL 就是我们前面所说的“栓野狗的链子” 如果你不栓起来迟早会出问题的。
比如:
在 free(p)之后,你用 if(NULL != p)这样的校验语句还能起作用吗?
例如:
char *p = (char *) malloc(100);
strcpy(p, “hello”);
free(p);
/* p 所指的内存被释放,但是 p 所指的地址仍然不变 */
?
if (NULL != p)
{
/* 没有起到防错作用 */
strcpy(p, “world”);
/* 出错 */
}

释放完块内存之后,没有把指针置 NULL,这个指针就成为了“野指针”,也有书叫“悬垂指针”。这是很危险的,而且也是经常出错的地方。所以一定要记住一条:free 完之后,一定要给指针置 NULL。

同时留一个问题:对 NULL 指针连续 free 多次会出错吗?为什么?如果让你来设计 free函数,你会怎么处理这个问题?注意:内存已经被释放了,但是继续通过指针来使用。这里一般有三种情况:
第一种:就是上面所说的,free(p)之后,继续通过 p 指针来访问内存。解决的办法就是给 p 置 NULL。
第二种:函数返回栈内存。这是初学者最容易犯的错误。比如在函数内部定义了一个数组,却用 return 语句返回指向该数组的指针。解决的办法就是弄明白栈上变量的生命周期。
第三种:内存使用太复杂,弄不清到底哪块内存被释放,哪块没有被释放。解决的办法是重新设计程序,改善对象之间的调用关系。

free函数释放内存相关推荐

  1. C语言调用 free 函数释放内存后指针指向及内存中的值是否改变的问题

    文章目录 1. 前言 2. 正文 2.1. "分配" 与 "释放" 2.2. 运行测试 2.2.1. VSCode 下使用 gcc 编译 2.2.2. VS20 ...

  2. c语言中free函数释放内存后,会怎么样?

    比如有一个 int* p 的指针,申请内存: p = (int*)malloc(sizeof(int)); 你就可以对 p 做这样的操作:*p = 54; 使用 free(p);那么就是切断了 p 对 ...

  3. python 堆栈溢出_python - 使用CFFI释放内存时,“ MemoryError:堆栈溢出”是什么意思? - 堆栈内存溢出...

    这一个问题, 这一个 . 我使用CFFI创建DLL,并从C ++应用程序中调用它. 我在问自己如何找到释放由DLL分配的内存的方法,我遵循@metal在其答案中提到的想法. 现在是我的Python代码 ...

  4. vector 释放内存 swap

    http://blog.csdn.net/jerryjbiao/article/details/7389233 相信大家看到swap这个词都一定不会感到陌生,甚至会有这样想法:这不就是简单的元素交换嘛 ...

  5. CMAP是否可以使用RemoveAll()释放内存?CMAP如何释放内存?

    是否可以使用RemoveAll释放内存?CMAP如何释放内存? 1.映射表类(CMap) 2.CMap的格式: 3.CMAP头文件 4.CMAP是否可以使用RemoveAll()释放内存? 5.Rem ...

  6. 关于C语言的malloc函数以及内存泄漏的问题

    malloc函数 malloc函数的原型: (void *)malloc(int size) malloc函数的返回值是一个void类型的指针,参数为int类型的数据,即申请分配的内存大小,单位是字节 ...

  7. PHP unset()函数销毁变量 但没有实现释放内存

    <?PHP $a = "hello";$b = &$a;unset( $b );echo $a; // 输出 helloecho $b; // 报错$b = &quo ...

  8. vector利用swap()函数进行内存的释放

    首先,vector与deque不同,其内存占用空间只会增长,不会减小.比如你首先分配了10,000个字节,然后erase掉后面9,999个,则虽然有效元素只有一个,但是内存占用仍为10,000个.所有 ...

  9. linux释放内存函数,LINUX上的getifaddrs()函数的内存释放有关问题

    LINUX上的getifaddrs()函数的内存释放有关问题 LINUX上的getifaddrs()函数的内存释放有关问题 日期:2014-05-16 浏览次数:20386 次 LINUX下的geti ...

最新文章

  1. 无准备,不编程——计算机达人成长之路(15)连载
  2. oracle普通用户使用dbms函数,oracle使用DBMS_SCHEDULER调度作业
  3. .configure
  4. 基于链表的快速排序C语言,双向链表的快速排序算法,编译通过,程序会崩溃,求助一下各位...
  5. arcgis js api前端完成面积测算
  6. OAuth2.0 授权码认证方式使用流程
  7. NOI2015 荷马史诗
  8. HDU - 2047
  9. book_note for《Linux程序设计》chapter3 Linux系统C语言开发工具
  10. gensim提取一个句子的关键词_包含关键字 关键词提取 的文章 - 科学空间|Scientific Spaces...
  11. 证明 总偏差平方和 = 回归平方和 + 残差平方和
  12. 性能优化-图片压缩格式的选择(ETC和ASTC)
  13. 点成分享 | 麦氏比浊仪在药敏试验中的应用
  14. 计算机名人堂(历届图灵奖获得者)
  15. 物联网通信技术期末复习7:第七章-典型物联网通信系统
  16. 思科、华为交换机链路聚合(LACP)配置实例
  17. 全景项目软件 krpano 入门通
  18. 二叉堆的实现(最大堆)
  19. 项目文档编制-招标书
  20. 图像处理:显著性区域检测总结(二)

热门文章

  1. php图片自动裁剪图片,php裁剪图片(支持定点裁剪)
  2. Java——网络编程(UDP与TCP通信及实现聊天案例)
  3. mac不能承受之烫-pycharm
  4. DBLP数据集简介及简单用法
  5. 微信支付缺憾:没有最短操作链优势
  6. 5月份的社保没有交,新公司又不给补缴,我该怎么办???
  7. 魔法王国java_网易2018校园招聘面试编程题真题与参考答案集合
  8. 字体颜色编码 html
  9. JavaScript根据数组id合并两个数组对象
  10. Java中PDF类如合同打印代码事例