【c++】内存管理

C++提供了new和delete操作符进行动态内存管理,不仅分配内存,还会调用构造函数创建对象。new[]和delete[]用于数组分配和释放。与C语言的malloc/free相比,new可以初始化,且在分配对象时会调用构造函数,释放时调用析构函数。operatornew和operatordelete是系统级别的内存分配和释放函数,new失败会抛出异常,malloc失败返回NULL。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ 动态内存管理方式:new 和 delete

我们都知道,在C语言中,通常使用malloc/calloc/realloc/free进行内存管理,这些在C++中可以继续使用,C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理,其主要的优点是,new 不只是分配了内存,它还创建了对象。

为给定变量分配堆内的内存:new
若该变量不需要动态内存时,释放该空间:delete
void Allocate memory()
{
    
    int* ptr1= new int; //动态申请一个int类型空间
    
    int* ptr2=new int(10); //动态申请一个int类型空间并初始化为10
    
    int* ptr3=new int[10]; //动态申请10个int类型空间,数组动态内存分配
    
    delete ptr1;       //释放该空间
    delete ptr2;
    delete[] ptr3;     //当申请的是多个空间时,释放时也要释放多个
}

new开辟的空间和malloc开辟出来的一样,都是需要我们用指针指向记录的。

在我们需要开辟几个连续的空间的时候,我们需要用到 new [ ] ,释放空间就要用到 delete [ ] 。

二维数组动态内存分配

int **array;
// 假定数组第一维长度为 m, 第二维长度为 n
// 动态分配空间
array = new int *[m]; //动态开辟m个int*类型的空间
for( int i=0; i<m; i++ )
{
    array[i] = new int [n];
}
//释放
for( int i=0; i<m; i++ )
{
    delete [] array[i];
}
delete [] array;

对象的动态内存分配

同样的,我们也可以利用new 和 delete 创建多个对象
class T{...};
T* ptr= new T[3]; //同时创建3个T类的对象数组
delete[] ptr;

如果要为一个包含3个 T 对象的数组分配内存,构造函数将被调用3 次,同样地,当删除这些对象时,析构函数也将被调用相同的次数(3次)。

new/delete和malloc/free的区别

  1. malloc申请的空间不会初始化,new可以初始化

普通初始化后加(),数组初始化加{}
int* ptr1=new int(2);
int* arr=new int[3]{1,2,3};
  1. malloc和free是函数,new和delete是操作符


  1. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,

如果是多个对象,[]中指定对象个数即可

int* ptr=(int*)malloc(sizeof(int)*100);
int*ptr2=new int[100];
  1. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型


  1. 申请自定义类型对象时,malloc/free不会调用构造函数与析构函数,而new会调用构造函数,delete在释放空间前会调用析构函数

class A
{
public:
    A()
    {
        cout<<"构造函数调用"<<endl;
    }
    ~A()
    {
        cout<<"析构函数调用"<<endl;
    }
private:
    int a;
    int b;
};
int main()
{
    A* a=new A[3];
    delete[] a;
    return 0;
}

由此可见,使用new和delete为对象动态开辟内存空间,会调用该对象相应的构造函数和析构,可以自动初始化成员变量,释放空间。


  1. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需

要捕获异常

operator new与operator delete函数

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是
系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过
operator delete全局函数来释放空间。
// operator new:
// 该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;
// 申请空间失败尝试执行空间不足应对措施,如果用户设置了应对措施,则继续申请,否则抛异常。
void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
    // try to allocate size bytes
    void* p;
    while ((p = malloc(size)) == 0)
        if (_callnewh(size) == 0)
        {
            // report no memory
            // 如果申请内存失败了,这里会抛出bad_alloc 类型异常
            static const std::bad_alloc nomem;
            _RAISE(nomem);
        }
    return (p);
}
 
// operator delete:
// 该函数最终是通过free来释放空间的
void operator delete(void* pUserData)
{
    _CrtMemBlockHeader* pHead;
    RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
    if (pUserData == NULL)
        return;
    _mlock(_HEAP_LOCK);  // block other threads
    __TRY
        // get a pointer to memory block header
        pHead = pHdr(pUserData);
    // verify block type
    _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
    _free_dbg(pUserData, pHead->nBlockUse);  //此处调用free函数
    __FINALLY
        _munlock(_HEAP_LOCK);  // release other threads
    __END_TRY_FINALLY
        return;
}
 
// free的实现
#define  free(p)        _free_dbg(p, _NORMAL_BLOCK)

operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值