【C++笔记】内存管理流食般投喂

声明:以下知识相关资料来自比特官网和小编手搓~
C/C++内存管理

++1、C/C++内存分布++

++2、C语言中动态内存管理方式:malloc/calloc/realloc/free++

++3、C++内存管理方式++

3.1、new/delete操作内置类型

3.2、new和delete操作自定义类型

++4、operator new 与 operator delete 函数++

++5、new 和 delete 的实现原理++

5.1、内置类型

5.2、自定义类型

++6、定位new表达式(placement-new)++

++7、malloc/free 和 new/delete 的区别++

1、C/C++内存分布

C语言和C++的内存划分是一样的,常见内存区域就是:栈区、堆区、静态区、常量区,现在推出命名更加官方的区域划分:静态区 -> 数据段;常量区 -> 代码段。

栈区:函数栈帧的创建,其空间就是在栈上申请的,常见的局部变量也在这,及时申请、销毁,还有函数参数、返回值等等。

堆区:当数据结构存储数据空间不够时,额外申请的空间都是在堆区上申请开辟的,这个区域是给操作者发挥的区域。

给点题目试试水:

cpp 复制代码
int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
    static int staticVar = 1;
    int localVar = 1;

    int num1[10] = { 1, 2, 3, 4 };
    char char2[] = "abcd";
    const char* pChar3 = "abcd";
    int* ptr1 = (int*)malloc(sizeof(int) * 4);
    int* ptr2 = (int*)calloc(4, sizeof(int));
    int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
    free(ptr1);
    free(ptr3);
}

2、C语言中动态内存管理方式:malloc/calloc/realloc/free

*3、*C++内存管理方式

C++这里用独有的 new 和 delete 操作符进行内存管理。

3.1、new/delete操作内置类型

cpp 复制代码
void Test()
{
    // 动态申请一个int类型的空间
    int* ptr4 = new int;
    
    // 动态申请一个int类型的空间并初始化为10
    int* ptr5 = new int(10);

    // 动态申请10个int类型的空间
    int* ptr6 = new int[10];

    delete ptr4;
    delete ptr5;
    delete[] ptr6; //格式一一对应
}

注意:申请&释放一个空间 -> new & delete;

申请&释放连续的空间 -> new[] & delete[]。

3.2、new和delete操作自定义类型

new/delete 和 malloc/free 的最大区别,就是 new/delete 除了会开空间,还会调用构造函数/析构函数。

cpp 复制代码
//现有一个 A类

int main()
{
    A* p1 = (A*)malloc(sizeof(A));
    A* p2 = new A(1);    
    free(p1);
    delete p2;

    A* p3 = (A*)malloc(sizeof(A) * 10);
    A* p4 = new A[10];
    free(p3);
    delete[] p4;

    return 0;
}

4、operator new 与 operator delete 函数

operator new 其实就是malloc的套个公司换个名的事,不过operator new解决了malloc申请完要手动验证是否申请成功,operator new是不需要管的,他自己会处理,申请失败了会抛异常。

operator delete同理也就是free套个公司换个名的事。

5、new 和 delete 的实现原理

5.1、内置类型

内置类型对于new/delete 与 malloc/free来说,基本是一样的,只不过对于单个空间和连续空间,用的是 new/delete 和 new[]/delete[];对于空间申请失败,new是抛异常,malloc是返回NULL。

5.2、自定义类型

new 的原理:

调用operator new函数申请空间,再调用构造函数对申请的空间进行构造。

底层:malloc + 构造

delete 的原理:

先调用析构函数,对申请的资源进行清理与释放。

底层:析构 + free

new T[N] 的原理:

调用operator new[]函数,实际是调用operator new函数申请N个对象空间;在申请的空间上进行N次构造函数的执行。

delete[] 的原理:

先调用N次析构函数,对N个对象申请的资源进行清理和释放;再调用operator delete[]函数,实际调用operator delete函数释放空间。

6、定位new表达式(placement-new)

定位new表达式的使用场景是配合着内存池进行使用的。内存池:生活费小金库,妈妈每月定期给我、爸爸、姐姐生活费,我们日常开销就在自己的生活费小金库里面取,不需要有一笔消费。就问妈妈要。放在内存池里面的空间只是有一些空间放那,我们可以找他要空间,但是对于自定义类型对象,要来空间的并没有调用构造函数进行初始化,这个工作就交给了 定位new表达式。

定位new表达式的使用方法:new(指针,指向空间)类型 / new(指针,指向空间)类型(实参,初始化值)

cpp 复制代码
int main()
{
    A* p1 = (A*)malloc(sizeof(A));
    new(p1)A;
    p1->~A(); // 成员函数并不包含在对象里,但是得通过对象去公共存储池里去调用
    free(p1);

    A* p2 = (A*)malloc(sizeof(A));
    new(p2)A(10);
    p2->~A();
    free(p2);

    return 0;
}

7、malloc/free 和 new/delete 的区别

相同点:在堆上申请空间,用户手动释放。

不同点:

1、malloc和free是函数;new和delete是操作符。

2、malloc申请空间不会初始化;new会初始化。

3、malloc申请空间需要计算申请空间大小;new申请多个空间,只要在 [] 里输入你想开的对象个数。

4、malloc返回值是void*,C++中,必须强转;new不需要,他后面跟的就是类型。

5、malloc申请空间失败返回NULL,使用时必须手动判空;new不需要,不过要捕获异常。

6、申请自定义类型时,malloc/free不会调用构造函数和析构函数;new在申请空间后会调用构造函数对实例化出的对象进行初始化,delete会先调用析构函数,将申请的资源进行清理和释放,再释放空间。

相关推荐
林夕071 小时前
Qt QML与C++混合编程实战指南
java·开发语言·数据库
csbysj20201 小时前
状态模式:软件设计模式的深度解析
开发语言
雪度娃娃1 小时前
行为型设计模式——备忘录模式
服务器·c++·设计模式·备忘录模式
khalil10201 小时前
代码随想录算法训练营Day-55 图论06 | 108.冗余连接、109.冗余连接II
c++·算法·leetcode·图论·并查集
进击的荆棘1 小时前
优选算法——字符串
开发语言·c++·算法·leetcode·字符串
山栀shanzhi1 小时前
长连接、短连接、心跳、断线重连
开发语言·网络·c++
Kiling_07041 小时前
Java Map集合详解与实战
java·开发语言·python·算法
SilentSamsara1 小时前
描述符协议:@property 与 @classmethod 的实现原理
开发语言·python·青少年编程
绝顶少年1 小时前
[特殊字符] curl_cffi vs requests:Python请求库的终极对决
开发语言·python