C/C++内存分配new与malloc详解

1. C++内存分配调用过程

C/C++内存分配new与malloc详解_第1张图片

​ 上图中,ptmalloc,tcmalloc与jemalloc等是malloc底层实现策略。相比之下,ptmalloc性能较弱,资源消耗较多,在高CPU核心数情况下jemalloc比tcmalloc性能要好。

总之,内存池管理主要针对小内存分配进行,而大内存块由系统调用进行分配,如mmap内存映射

​ C/C++内存分配原语有malloc,new,::operator new()和allocate(),其中可否重载关系如下:

分配 释放 类别 可否重载
malloc() free() C语言 不可
new delete C++表达式 不可
operator new() operator delete() C++函数
allocator::allocate() allocator::deallocate() C++标准库空间分配器 视情况而定

2. C++中new/delete的四种形式

1)::operator new/::operator delete 这是全局的new/delete,只是简单的对malloc/free 进行封装。当使用不带属性限定符(::)的operator new/operator delete时,如果没有重载,系统会调用全局的new/delete分配空间。

2)new expression new表达式,编译器会将其翻译为三条语句:

// ---------------- 分配空间 ---------------- //
obj_class* mem = new obj_class(init_val); 

// 翻译为以下三条语句
void* mem = operator new(sizeof(obj_class));   // 使用new分配空间,其实质使用malloc分配

mem = static_cast(mem);           // 强制转型

mem->obj_class(init_val);                     // 使用obj_class构造函数进行初始化

// ---------------- 释放空间 ---------------- //
delete mem;

// 翻译为以下两条语句
obj_class::~obj_class(mem);  // 调用析构函数
operator delete(mem);        // 释放空间

3)array new new多个数组,例如:

type* ptr = new typep[size];  // 分配空间

delete[] ptr;   // 释放空间

PS:当type的析构函数是无意义的,即 is_trivially_destructible::value == true,此时释放空间时,可以不加"[]",也不会出现内存泄露。当然,最好加上"[]",这样代码更加友好。

4)placement new 除了必须的第一个参数,还含有额外的参数的operator new 的重载。

:在正常调用placement new时,使用delete ptr释放内存;只有当调用placement new抛出异常时,系统会调用用户重载的placement delete进行处理,防止内存泄露。

3. new handler

当系统调用new分配内存抛出异常 bad_alloc_exception 之前,会调用(不止一次)用户可指定的handler进行处理。而new handler用于出现exception时,用户指定程序的处理方法,其形式如下。

typedef void(*new_handler)();   // 定义的handler函数指针
new_handler set_new_handler(new_handler ptr) throw();   // 设置新的 handler 处理函数

一般处理方法是调用abort()或者exit()

:本文主要参照侯捷老师的《内存管理》讲解。

你可能感兴趣的:(C++,c++,内存管理,malloc)