0%

认识C++内存管理的工具 (三)

13. 重载类本身的operator 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
using namespace std;
struct A
{
A()
{
cout << "A() : this:" << this << endl;
}
~A()
{
cout << "~A(): this: " << this << endl;
}

// 这个函数写不写 static 都会被编译器做成 static
static void* operator new(size_t len)
{
return malloc(len);
}

static void operator delete(void* ptr, size_t len)
{
return free(ptr);
}
};

int main()
{
// 调用 A::operator new 版本
A* a = new A();

// 调用全局的 operator new, 如果想调用 A 的版本, 则需显式调用 A::operator new()
void* b = operator new(sizeof(A));


A* c = ::new A(); // 调用全局的 operator new
void* d = ::new A(); // 调用全局的 operator new

delete a; // 先调用 A 的析构函数, 再调用 A 的 operator delete
delete b; // 直接调用了全局的 operator delete
::delete c;
::delete d;
}

image-20210316211007882

14. 本质就是重载new

new是关键字,编译器看到new,会转换成operator new的调用。

image-20210316211821850

image-20210316211849406

image-20210316211942624

15. 重载new()/delete()

image-20210316212107044

image-20210316212317475

16. 关于多参new对应的delete

image-20210316212449598

  • 上面重载了参数不一的operator new(),那是不是要重载对应的operator delete()呢?

    理论上delete的工作只是为了释放内存,所以只需要一个指针就可以了,但C++在语法上支持多参的delete重载,但delete的调用格式只有delete ptr,所以关于重载的delete版本什么时候被调用,并不是用户手动调用,而是对应版本的Ctor发生异常后,会由crt来调用对应的delete

17. basic_string使用new(extra)扩充申请量

image-20210316214052184

18. new_handler

image-20210317210723036

image-20210317211006818

image-20210317211425498

image-20210317211445418