关于C/C++中的内存泄漏——程序员面试高频题

时间:2022-09-05 23:00:19


前几天面试多益网络的时候,面试官就问到了C/C++中的内存泄露问题。这也是很多公司面试时候的高频题,好吧,那就来学习下吧~

到底什么是内存泄漏?是什么导致了内存泄漏?如何避免?又如何检测呢?


1)什么是内存泄漏

简单来讲,内存泄露是指程序中一块不再使用的内存没有被释放,造成内存保持占用状态,使操作系统不能将内存分配给其它的程序(进程)。内存泄露不是一个立即会引发故障的错误,但是它将消耗系统内存。

2) 什么导致了内存泄漏?

通过定义很明显的,我们用malloc/new申请的内存块,再利用完之后我们忘了free/delete它了,导致内存一直被占用。

下面给出一个小例子:

  1. void fun()  
  2. {  
  3.     char *p;  
  4.     p = (char*)malloc(sizeof(char)*20);  
  5.     if(NULL !=p)  
  6.     {  
  7.         strcpy(p,”hello”);  
  8.         printf(“p = %s\s”,p);  
  9.     }  
  10.     return;  
  11. }  
这里面,我们用malloc申请的内存块,用完之后,没有用free释放掉,这样,最终会造成20个字节的内存泄漏。正确的做法应该是:

  1. void fun()  
  2. {  
  3.     char *p;  
  4.     p = (char*)malloc(sizeof(char)*20);  
  5.     if(NULL !=p)  
  6.     {  
  7.         strcpy(p,”hello”);  
  8.         printf(“p = %s\s”,p);  
  9.     }  
  10.     return;  
  11.     free(p);
  12. }  

这样就可以很好地避免了内存泄漏啦~

3) 如何检测内存泄漏?

当然上面的例子是很简单的,一眼就可以看出来的。当我们在一个比较大的项目里面,发生泄漏了,该怎么找?所以学习一些内存泄漏的检测方法也是很有必要的。

Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄漏检测工具,该软件以库形式与用户的被测工程一起使用,由于VLD是按LGPL(GNU LESSER GENERAL PUBLIC LICENSE)协议对外开源,所以使用VLD是安全的,不必担心版权问题。

使用VLD很简单,只须在包含入口函数的CPP或C文件中把vld.h头文件包含进来即可。该include语句要求放在最前面,如果当前工程定义预编译head文件(如stdafx.h),则放在“#include <stdafx.h>”语句之后就可以了。之后正常编译、按Debug方式运行被测程序,等程序运行结束时,查阅VC的output窗口,会有“Visual Leak Detector is now exiting.”一句打印信息,在这条件信息之前,如果当前程序没有内存泄露会有“No memory leaks detected.”信息打印,但如果有内存泄露,将有类似如下信息打印:

    C:/VcTester21/sample/vc6/SampleMain.c (80): main

    crt0.c (206): mainCRTStartup

    0x7C816FD7 (File and line number not available): RegisterWaitForInputIdle

  Data:

      CD CD CD CD    CD                    ........ ........

   

Visual Leak Detector detected 1 memory leak.

这个信息指明当前发生内存泄露所在的函数及源文件行号,泄露内存块的地址、长度及当前内存值。用鼠标双击指示源码行的提示信息,VC即自动跳转到相应代码行,我们就很方便的知道是哪一行出错了。

4)相关的内存溢出

既然说到了内存泄露,我们最后还提下内存溢出吧。内存溢出指你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,就是溢出。