C/C++什么是内存泄露,内存泄露如何避免?

您所在的位置:网站首页 handler为什么会造成内存泄漏 C/C++什么是内存泄露,内存泄露如何避免?

C/C++什么是内存泄露,内存泄露如何避免?

2024-01-28 19:40| 来源: 网络整理| 查看: 265

C/C++什么是内存泄露,内存泄露如何避免? 1. 内存溢出2. 内存泄漏3. 造成内存泄露常见的三种情况3.1 指针重新赋值3.2 错误的内存释放3.3 返回值的不正确处理 4. 如何避免内存泄露?5. 内存泄露检测工具valgrind

1. 内存溢出

  内存溢出 OOM (out of memory),是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个int,但给它存了long才能存下的数,那就是内存溢出。

2. 内存泄漏

  内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。最终的结果就是导致OOM。   内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。

3. 造成内存泄露常见的三种情况

1,指针重新赋值 2,错误的内存释放 3,返回值的不正确处理

3.1 指针重新赋值

如下代码:

char * p = (char *)malloc(10); char * np = (char *)malloc(10);

其中,指针变量 p 和 np 分别被分配了 10 个字节的内存。 在这里插入图片描述如果程序需要执行如下赋值语句:

p=np;

这时候,指针变量 p 被 np 指针重新赋值,其结果是 p 以前所指向的内存位置变成了孤立的内存。它无法释放,因为没有指向该位置的引用,从而导致 10 字节的内存泄漏。 在这里插入图片描述因此,在对指针赋值前,一定确保内存位置不会变为孤立的。

类似的情况,连续重复new的情况也是类似:

int *p = new int; p = new int...;//错误 3.2 错误的内存释放

假设有一个指针变量 p,它指向一个 10 字节的内存位置。该内存位置的第三个字节又指向某个动态分配的 10 字节的内存位置。 在这里插入图片描述如果程序需要执行如下赋值语句时:

free(p);

很显然,如果通过调用 free 来释放指针 p,则 np 指针也会因此而变得无效。np 以前所指向的内存位置也无法释放,因为已经没有指向该位置的指针。换句话说,np 所指向的内存位置变为孤立的,从而导致内存泄漏。 因此,每当释放结构化的元素,而该元素又包含指向动态分配的内存位置的指针时,应首先遍历子内存位置(如本示例中的 np),并从那里开始释放,然后再遍历回父节点,如下面的代码所示:

free(p->np); free(p); 3.3 返回值的不正确处理

有时候,某些函数会返回对动态分配的内存的引用,如下面的示例代码所示:

char *f(){ return (char *)malloc(10); } void f1(){ f(); }

函数 f1 中对 f 函数的调用并未处理该内存位置的返回地址,其结果将导致 f 函数所分配的 10 个字节的块丢失,并导致内存泄漏。 4) 在内存分配后忘记使用 free 进行释放

4. 如何避免内存泄露? 确保没有在访问空指针。每个内存分配函数都应该有一个 free 函数与之对应,alloca 函数除外。每次分配内存之后都应该及时进行初始化,可以结合 memset 函数进行初始化,calloc 函数除外。每当向指针写入值时,都要确保对可用字节数和所写入的字节数进行交叉核对。在对指针赋值前,一定要确保没有内存位置会变为孤立的。每当释放结构化的元素(而该元素又包含指向动态分配的内存位置的指针)时,都应先遍历子内存位置并从那里开始释放,然后再遍历回父节点。始终正确处理返回动态分配的内存引用的函数返回值。 5. 内存泄露检测工具valgrind

这是一个linux下的内存泄露检测工具 内存泄露情况: 在这里插入图片描述 无内存泄露情况: 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3