内存泄漏概念:内存泄漏时指动态申请的内存空间没有正常释放,但是也不能继续使用的情况。
例如:
char *ch1; ch1 = new char(\'A\'); char = *ch2 = new char; ch1 =ch2;
程序执行后,指针ch1和ch2指向同一个地址单元,而原来的ch1所申请的存放字符A的空间就不可能再使用,产生了内存泄漏。
最常出现的情况是申请了动态内存后,没有正常的使用delete来释放,导致内存泄漏。
1.当基类指针指向子类对象即在子类中动态申请内存时,如果基类的析构函数不是virtual,那么子类的析构函数将不会被调用,子类的资源没有正确是释放,因此造成内存泄露
指针悬挂概念:指指针指向一个已经释放的地址空间。
例如:
char *ch1, *ch2; ch1 = new char; ch2 =ch1; *ch2 = \'B\'; delete ch1;
程序执行到这里,指针ch2就是指向了一个已经释放的地址空间,形成指针悬挂。
如果还要用delete ch2 来释放ch2的空间,就会出现运行错误,因为实际上不存在可以释放的空间。
野指针:指向被释放的或者访问受限内存的指针。
造成野指针的原因:
- 指针变量没有被初始化(如果值不定,可以初始化为NULL)
- 指针被free或者delete后,没有置为NULL, free和delete只是把指针所指向的内存给释放掉,并没有把指针本身干掉,此时指针指向的是“垃圾”内存。释放后的指针应该被置为NULL.
- 指针操作超越了变量的作用范围,比如返回指向栈内存的指针就是野指针。
内存泄漏危害:
从用户使用程序的角度来看,内存泄漏本身不会产生什么危害。作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积。而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。存在内存泄漏问题的程序除了会占用更多的内存外,还会使程序的性能急剧下降。对于服务器而言,如果出现这种情况,即使系统不崩溃,也会严重影响使用。
不过还有一点,如果你的程序内存泄露正好写到了系统使用的内存或者其他程序使用的内存地址,那么就会导致系统异常或者程序崩溃