内存泄漏(Memory Leak)

什么是内存泄漏(Memory Leak)?

简单地说就是申请了一块内存空间,使用完毕后没有释放掉。它的一般表现方式是程序运行时间越长,占用内存越多,最终用尽全部内存,整个系统崩溃。由程序申请的一块内存,且没有任何一个指针指向它,那么这块内存就泄露了。

内存泄漏一般指的是堆内存的泄漏。堆内存是指程序从堆中分配的、大小任意的(内存块的大小可以在程序运行期决定)、使用完后必须显示的释放的内存。应用程序一般使用malloc、realloc、new 等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用 free 或 delete 释放该内存块。否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。

实例:
内存泄漏(Memory Leak)
编译时会出现Segmetation fault,main函数中的ptr,get_memory中的ptr,两者的地址不同,函数调用按值传递,NULL的值传给了get_memory的ptr,当函数结束时,形参的生存期结束了,并没有改变实参的值。因此main函数中ptr的值仍然是NULL。访问了不存在的内存,解引用空指针了,因此提示Segmetation fault。同时,get_memory返回后,ptr不复存在,malloc分配一段内存空间无法找到地址,因此在main函数中无法调用free();因此(在程序运行期间)存在内存泄漏。

正确修改:(传参)
内存泄漏(Memory Leak)
(返回值)
内存泄漏(Memory Leak)
错误实例:
内存泄漏(Memory Leak)
栈区数据动态消亡,
printf函数会调用局部变量 也是栈区
栈区内容离开函数体后不受保护 printf函数调用可能会修改它的值
会打印出随机值。

内存泄漏的后果

程序运行后置之不理,并且随着时间的流失消耗越来越多的内存(比如服务器上的后台任务,尤其是嵌入式系统中的后台任务,这些任务可能被运行后很多年内都置之不理);
新的内存被频繁地分配,比如当显示电脑游戏或动画视频画面时;
程序能够请求未被释放的内存(比如共享内存),甚至是在程序终止的时候;
泄漏在操作系统内部发生;
泄漏在系统关键驱动中发生;
内存非常有限,比如在嵌入式系统或便携设备中;
当运行于一个终止时内存并不自动释放的操作系统(比如AmigaOS)之上,而且一旦丢失只能通过重启来恢复。

如何发现内存泄漏

有些简单的内存泄漏问题可以从在代码的检查阶段确定。还有些泄漏比较严重的,即在很短的时间内导致程序或系统崩溃,或者系统报告没有足够内存,也比较容易发现。最困难的就是泄漏比较缓慢,需要观测几天、几周甚至几个月才能看到明显异常现象。那么如何在比较短的时间内检测出有没有潜在的内存泄漏问题呢?实际上不同的系统都带有内存监视工具,我们可以从监视工具收集一段时间内的堆栈内存信息,观测增长趋势,来确定是否有内存泄漏。在 Linux 平台可以用 ps 命令,来监视内存的使用,比如下面的命令 (观测指定进程的VSZ值):

ps -aux

Linux下内存泄漏工具
https://www.cnblogs.com/guochaoxxl/p/6970090.html