重载new与delete
- new和delete的机制
new分3步,首先new表达式用一个名为operarot new或者operator new[]的标准库函数来分配一块足够大的原始内存;然后编译器运行相应的构造函数来构造;最后构造完成之后返回一个指向该对象的指针。delete分2步,首先对指针指向的内存执行析构操作,然后调用operator delete或者operator delete[]释放相应空间。
默认的new,new[],delete,delete[]
void* operator new(size_t)
void* operator new[](size_t)
void operator delete(void*)
void operator delete[](void*)
注意对于重载new与new[],必须返回void,并且第一个参数必须是size_t,且不能有默认实参,`void operator new(size_t, void*)` 这种形式不能重载,只能供标准库使用。运用重载new与delete来检测内存泄露
内存泄漏就是new出来的内存没有通过delete合理的释放掉。new和delete这两个函数就是关键点。可以重载new和delete,每次new中开辟一块内存就用链表把这个内存的信息保存下来,每次用delete删除一块内存就从链表中删除这块内存的记录。代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using namespace std;
struct node
{
unsigned int line;
void* ptr;
node* next;
};
class mem_list
{
public:
void insert(unsigned int line, void* ptr)
{
node* p_node = (node*) malloc(sizeof(node));
p_node->line = line;
p_node->ptr = ptr;
p_node->next = nullptr;
if(head == nullptr)
{
head = p_node;
}
else
{
p_node->next = head;
head = p_node;
}
}
void remove(void* ptr)
{
node* p_cur = head;
node* p_pre = nullptr;
while(p_cur != nullptr)
{
if(p_cur->ptr == ptr)
{
break;
}
else
{
p_pre = p_cur;
p_cur = p_cur->next;
}
}
if(p_cur == nullptr)
{
cout << "delete an unknown memory!" << endl;
}
else
{
p_pre->next = p_cur->next;
free(p_cur);
p_cur = nullptr;
}
}
void print()
{
if(head == nullptr)
{
cout << "no memory leak!" << endl;
}
else
{
node* p_cur = head;
while(p_cur != nullptr)
{
cout << "a memory leak in line: " << p_cur->line << endl;
p_cur = p_cur->next;
}
}
}
private:
node* head;
};
mem_list li; //全局的链表
void* operator new(size_t size, unsigned int line)
{
void* ptr = malloc(size);
li.insert(line, ptr);
return ptr;
}
void operator delete(void* ptr)
{
free(ptr);
li.remove(ptr);
}
int main()
{
unsigned int l = 111;
int* p = new int;
li.print();
return 0;
}