当前位置: 首页 > 科技观察

内存溢出和内存泄漏分析

时间:2023-03-21 01:42:12 科技观察

我们在实际编程中经常会谈到内存溢出和内存泄漏,尤其是对于C/C++程序(以下代码示例都是C/C++),因为这时候我们会直接Deal有记忆。然而,很多时候我们对这两个概念并不完全理解,有时甚至会把它们颠倒过来混淆。其实从命名上也可以理解内存溢出和内存泄漏。让我举一个可能不合适的例子。这就好比往水箱里取水。本来,这个缸只能装5桶水。第五个桶装满后,还得安装第六个桶。水箱里的水自然会溢出来。这就是“内存溢出”。;水箱装满水后,就没人用了。第二天发现缸里的水少了一半,第三天一滴也没有了。那个洞呢?没理由,好玩,任性)。这就好比申请了一块内存却忘了释放,造成“内存泄漏”。下面将简要解释这两个概念。首先,让我们谈谈内存溢出。简单的说,内存溢出就是请求的内存分配超出了系统所能提供的。比如你申请一个10字节的内存空间,你非要往里面塞11字节的数据,自然是满溢出来的(如代码示例1)。其实数组越界也是一种内存溢出,比如写入数据超出数组的范围(读取数组数据越界不算内存溢出)。数组越界填充后,如果再塞进去,就会占用栈内存(一般数组声明为局部变量,局部变量自动在栈区分配内存)。越界部分作为局部变量占用栈内存,因为栈从RAM底部增长(存储数据),而程序中的其他数据是从上往下运行的,所以当栈存储的越来越多,越积累越高,程序运行时栈会遇到数据,两者会占据整个RAM内存。这时候栈会不断被消耗,栈会向上增长,直接覆盖掉程序运行时需要的变量,程序就会跑掉。看来内存溢出也很可怕。voidarr_test(){intarr[10];arr[10]=10;}然后说说内存泄漏,一般来说,内存泄漏是指堆内存泄漏(Heapleak),在堆上动态申请内存,使用后如果不及时释放,就会发生内存泄漏。顺便说一句,如果指针指向的内存被释放,但指针没有立即设置为NULL,就会造成野指针(如代码示例2)。内存泄漏可能不会被注意到,也可能不会造成任何危害,但内存泄漏累积起来就会导致内存耗尽,后果很严重。例如,在循环体中发生内存泄漏。当然,还有其他形式的内存泄漏,比如系统资源泄漏(Resourceleak)导致的内存泄漏。根据内存泄漏的频率,一般的内存泄漏可以分为以下四种类型:频繁内存泄漏;偶尔的内存泄漏;一次性内存泄漏;隐式内存泄漏。1voidheap-leap_test2{3char*p=(char*)malloc(sizeof(char));4//exetask5free(p);//如果指针p指向的内存空间没有释放,就会导致内存泄漏。6p=NULL;//如果指针p没有设置为NULL,那么p就会变成野指针。7}