
内存管理是十分重要的内容,企业开发中多有服务器宕机的大事故,比如:
其中内存管理可能占有一定原因,只有我们打好内存管理的基础才能为大家做出贡献,那不然就只能赶快跑路了。 首先我们就要了解内存分布的情况是什么样的。

其中
堆和栈是我们常用到的区域,栈不需要我们进行管理,需要我们多加注意的就是堆区域
我们回忆一下C语言的内存管理,大概是下面四个函数的使用:
接下来我们来看C++ 的内存管理,来欣赏祖师爷的绝妙手笔~
首先C语言的内存管理可以在C++中使用,但是有些地方就显得比较复杂,因此我们需要C++的内存管理 C++的内存管理是通过new 操作符 和 delete 操作符来实现的。
首先来看对于内置类型的操作:
int main(){
//开辟申请一个int的空间
int* p1 = new int;
//开辟申请一个int的空间,并初始化为10
int* p2 = new int(10);
//开辟申请 3 个int的空间
int* p3 = new int[3];
//开辟申请 3 个int的空间,并初始化为1,2,3
int* p4 = new int[3] {1, 2, 3};
//释放空间
delete p1;
delete p2;
delete[] p3;
delete[] p4;
return 0;
}
通过一个new 就可以完成复杂的开辟空间操作。

注意: 每次使用完空间,一定要释放掉。申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用 new[]和delete[],注意:匹配起来使用。
对于自定义类型 new/delete 和 malloc/free最大区别是 new / delete对于【自定义类型】除了开空间还会调用构造函数和析构函数 来看使用:
#include"Date.h"
int main() {
Date* p1 = new Date(2024, 2, 28);
p1->show();
delete p1;
return 0;
}
注意:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会
new 和 delete 是用户进行动态内存申请和释放的操作符,而 operator new与operator delete 是系统提供的全局函数,new 在底层就是通过调用operator new 来申请空间,delete就是通过operator delete 来释放空间。 到这里我们大概就知道了operator new与operator delete函数应该是对 malloc 和 free的封装。 我们进入反汇编就可以验证这一点:
// new() Fallback Ordering
//
// +----------+
// |new_scalar<---------------+
// +----^-----+ |
// | |
// +----+-------------+ +----+----+
// |new_scalar_nothrow| |new_array|
// +------------------+ +----^----+
// |
// +------------+----+
// |new_array_nothrow|
// +-----------------+
_CRT_SECURITYCRITICAL_ATTRIBUTE
void* __CRTDECL operator new(size_t const size)
{
00007FF7C6A17D60 mov qword ptr [rsp+8],rcx
00007FF7C6A17D65 sub rsp,38h
for (;;)
{
if (void* const block = malloc(size))
00007FF7C6A17D69 mov rcx,qword ptr [size]
00007FF7C6A17D6E call malloc (07FF7C6A11401h)
00007FF7C6A17D73 mov qword ptr [rsp+20h],rax
00007FF7C6A17D78 cmp qword ptr [rsp+20h],0
00007FF7C6A17D7E je operator new+27h (07FF7C6A17D87h)
{
return block;
00007FF7C6A17D80 mov rax,qword ptr [rsp+20h]
00007FF7C6A17D85 jmp operator new+4Bh (07FF7C6A17DABh)
}
if (_callnewh(size) == 0)
00007FF7C6A17D87 mov rcx,qword ptr [size]
00007FF7C6A17D8C call _callnewh (07FF7C6A1150Ah)
00007FF7C6A17D91 test eax,eax
00007FF7C6A17D93 jne operator new+49h (07FF7C6A17DA9h)
{
if (size == SIZE_MAX)
00007FF7C6A17D95 cmp qword ptr [size],0FFFFFFFFFFFFFFFFh
00007FF7C6A17D9B jne operator new+44h (07FF7C6A17DA4h)
{
__scrt_throw_std_bad_array_new_length();
00007FF7C6A17D9D call __scrt_throw_std_bad_array_new_length (07FF7C6A1170Dh)
}
00007FF7C6A17DA2 jmp operator new+49h (07FF7C6A17DA9h)
else
{
__scrt_throw_std_bad_alloc();
00007FF7C6A17DA4 call __scrt_throw_std_bad_alloc (07FF7C6A111E0h)
}
}
// The new handler was successful; try to allocate again...
}
00007FF7C6A17DA9 jmp operator new+9h (07FF7C6A17D69h)
}
00007FF7C6A17DAB add rsp,38h
00007FF7C6A17DAF ret 
显然operator new与operator delete函数应该是对 malloc 和 free的封装。
如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是: new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL,需要我们来判断异常


malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。 不同的地方是: