内存泄露
内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
常见的内存泄漏原因及解决方案
1. 析构函数中未匹配地释放内存
2. 基类的析构函数没有设为虚函数
3. 关于指针数组释放
4. 拷贝构造函数和运算符重载的问题
5. shared_ptr的循环引用问题
野指针
可能会造成野指针的情况:
1)指针变量没有被初始化(如果值不定,可以初始化为NULL)
2)指针所指内存被释放后,没有立即置为NULL。
3)指针操作超越了变量的作用范围,比如返回指向栈内存的指针就是野指针。
内存泄漏检测
常见方法:
- 使用vs自带的性能监视器进行内存泄露检测,可以定位具体函数
- 添加使用Debug_New宏代替new/malloc,观察代码申请释放情况
内存溢出
内存溢出(Out Of Memory,简称OOM)是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于能提供的最大内存。此时程序就运行不了,系统会提示内存溢出,有时候会自动关闭软件,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件,而由系统配置、数据流、用户代码等原因而导致的内存溢出错误,即使用户重新执行任务依然无法避免
内存越界
内存越界,内存读越界,即读了不属于自己的数据。如果所读的内存地址是无效的,程序立刻崩溃;如果所读内存地址是有效的,在读的时候不会马上出现问题,但由于读到的数据是随机的,因此它会造成不可预料的后果。
例如你向系统申请了一块内存,在使用这块内存的时候,超出了你申请的范围。例如,你明明申请的是100字节的空间,但是你由于某种原因写入了120字节,这就是内存访问越界。
内存访问越界的后果是:
- 你的写入破坏了本不属于你的空间。
栈溢出
函数调用栈是指程序运行时内存一段连续的区域,用来保存函数运行时的状态信息,包括函数参数与局部变量等。称之为“栈”是因为发生函数调用时,调用函数(caller)的状态被保存在栈内,被调用函数(callee)的状态被压入调用栈的栈顶;在函数调用结束时,栈顶的函数(callee)状态被弹出,栈顶恢复到调用函数(caller)的状态。函数调用栈在内存中从高地址向低地址生长,所以栈顶对应的内存地址在压栈时变小,退栈时变大。
栈溢出就是指超出栈的最大内存。栈内存最大是2M。
出现栈内存溢出的常见原因有2个:
1> 函数调用层次过深,每调用一次,函数的参数、局部变量等信息就压一次栈。(一般就是递归层数太深)
2> 局部静态变量体积太大