内存陷阱

str = (char *) malloc(15);

free(str)

free(str)

常见内存问题

内存泄漏(浪费可耻)

什么是内存泄漏

内存泄漏指应用程序用了一段内存,但是忘了释放,导致了内存的浪费。

内存泄漏的后果

内存泄漏的的后果从轻到重可能体现为性能不良到内存彻底用尽从而导致程序崩溃,在以下情况,内存泄漏后果很严重

  1. 一个生命周期较长的程序运行后导致内存逐渐流失
  2. 新的内存被频繁分配导致内存快速流失
  3. 泄漏发生在关键位置,例如操作系统或驱动程序中
  4. 在内存极其有限的系统中发生泄漏
  5. 在程序运行结束后不会自动释放内存的操作系统上发生泄漏

常见内存泄漏原因

申请/释放未配对
  1. 最单纯的malloc忘记free
  2. 内存分配和释放在不同的函数体内,可能忘记了释放
  3. 在malloc和free之间发生了错误导致free未能执行
  4. 不匹配使用new[]/delete[]
基类析构函数未定义为虚函数

这种情况下如果基类指针指向子类,delete该对象,子类部分不会被释放

delete void指针导致析构函数未调用

在C++中,delete实际是做了两件事

  • 调用析构函数
  • 释放空间

在下面的代码中,如果我们去delete一个void指针,会导致析构函数没有被调用,而析构函数中可能会做一些内存释放工作,导致析构失败

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Object {
private:
void* data;
const int size;
const char id;
public:
Object(int sz, char c):size(sz), id(c){
data = new char[size];
cout << "Object() " << id << " size = " << size << endl;
}
~Object(){
cout << "~Object() " << id << endl
delete []data; // !!!data不会被释放
}
};
int main() {
Object* a = new Object(10, 'A');//Object*指针指向一个Object对象;
void* b = new Object(20, 'B');//void*指针指向一个Object对象;
delete a;//执行delete,编译器自动调用析构函数;
delete b;//执行delete,编译器不会调用析构函数,导致data占用内存没有得到回收;

return 0;
}

常见内存问题检测

内存泄漏检测

mtrace

解决方案

参考文献

0%