C++内存管理

本文详细解释了C++中内存管理的不同方式,包括new,delete,malloc,free的用法、原理以及它们在内置类型和自定义类型上的区别。重点强调了new和delete如何处理构造函数和析构函数,以及malloc和free与之的对比。
摘要由CSDN通过智能技术生成

1.c++内存管理方式

1.c++的内置类型

申请一个空间并初始化

#include<iostream>
using namespace std;
int main()
{
//int*ptr1=new int;//申请1个int的空间
    int* ptr = new int(10);//申请10个int的空间并初始化为10
 delete ptr;//释放单个空间

    return 0;
}

申请连续的空间并初始化

#include<iostream>
using namespace std;
int main()
{
    //int* ptr = new int(10);
    //int* ptr1 = new int[10];//申请10个int的空间
    int* ptr = new int[10] {1, 2, 3, 4};//申请10个int的空间并初始化
 delete []ptr;//释放连续空间
    return 0;
}

这里相当于部分初始化,只初始化了前4个空间,其他空间默认为0

总结
申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]

2.c++的自定义类型

#include<iostream>
using namespace std;
class A
{
public:
    A(int a = 0)
        : _a(a)
    {
        cout << "A():" << this << endl;
    }
    ~A()
    {
        cout << "~A():" << this << endl;
    }
private:
    int _a;
};

int main()
{
    A* p = (A*)malloc(sizeof(A) * 10);
    free(p);
    A* p1 = new A[2];
    delete[]p1;
    return 0;
}

申请2个A类型的空间,调用2次构造函数释放空间,并调用2次析构函数
虽然写入了malloc在堆开辟10个A类型空间,free释放空间,但是没有调用构造和析构函数

2.总结
在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。

3.operator new与operator delete函数

operator new与operator delete函数是库里面提供的两个全局函数,不是运算符重载
new和delete是用户进行动态内存申请和释放的操作符,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。



#include <iostream>
using namespace std;
#include<iostream>
using namespace std;
class A
{
public:
    A(int a = 0)
        : _a(a)
    {
        cout << "A():" << this << endl;
    }
    ~A()
    {
        cout << "~A():" << this << endl;
    }
private:
    int _a;
};

int main()
{
    //申请空间 operator new  封装 malloc
    //在用operator delete p1指向空间
    A* p1 = new A;
    delete p1;

    //申请空间 operator new  封装 malloc
      //在用operator delete []p2指向空间
    A* p2 = new A[10];
    delete []p2;
    return 0;
}

4.new和delete的实现原理

1.内置类型

对于是内置类型,malloc/free与new/delete功能基本一致,但new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间

#include<iostream>
using namespace std;
int main()
{
    int* p1 = (int*)operator new(sizeof(int));//new失败抛异常
    int* p2 = (int*)malloc(sizeof(int));
    if (p2 == nullptr)//malloc失败返回空
    {
        perror("malloc fail");
    }
    return 0;
}

new机制与malloc也不同,new申请空间失败会抛异常,而malloc失败返回nullptr

2.自定义类型

#include<iostream>
using namespace std;
class A
{
public:
    A(int a = 0)
        : _a(a)
    {
        cout << "A():" << this << endl;
    }
    ~A()
    {
        cout << "~A():" << this << endl;
    }
private:
    int _a;
};

int main()
{
    A* p1 = new A;//先创建空间,在调用构造函数,
    delete p1;//delete先调用析构函数,在释放空间
    //-----------------------------------
    A* p2 = new A[10];//先创建空间,在调用构造函数10次
    delete[]p2;//delete先调用析构函数10次,在释放空间
    return 0;
}

new先申请一个A的空间,再调用构造函数,delete先调用析构函数,再释放空间
new先申请10个A类型的空间,再调用构造函数10次,delete先调用析构函数10次,再释放空间

5.malloc/free与new/delete的区别

1.共同点

都是从堆上申请空间,并且需要用户手动释放

2.不同点

用法角度

1.malloc和free是函数,new和delete是操作符
2.malloc申请的空间不会初始化,new可以初始化
3.malloc申请空间时,需要手动计算空间大小并传递,new只需其后跟上空间的类型即可,如果是多个对象时,[]指定对象个数即可
4.malloc返回值为void*,在使用必须强转,new不需要,因为new后跟的是空间类型

底层原理角度

malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new失败会抛异常
申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造和析构函数,而new申请空间后会调用构造函数完成对象的初始化,delete在释放空间会调用析构函数完成空间中的资源的清理

  • 16
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值