C++中的动态内存管理(new/delete)

目录

C++动态内存管理

new/delete 操作内置类型

new/delete操作自定义类型

new/delete执行原理

内置类型

自定义类型

new的原理

delete的原理

 new  T[N]的原理

delete [] 的原理


前言:在C语言中,我们开辟空间时,通常使用malloc、free 和 realloc 等进行空间开辟,在C++中,我们也可以使用C语言中的方法,但是有些地方就会比较麻烦,所以C++就提出了自己的内存管理方法:通过 new 和 delete 操作符来进行动态内存开辟管理。

C++动态内存管理

new/delete 操作内置类型

void Test ()
{
  //动态申请一个int类型的空间
  int* ptr1 = new int ;
  
  // 动态申请一个int类型的空间并初始化为1
  int* ptr2 = new int (1);
  
  //动态申请10个连续的int类型的空间
  int* ptr3 = new int [10];

  delete ptr1;
  delete ptr2;
  delete[] ptr3;
}
  • 申请和释放单个元素空间使用的是 new 和 delete 操作符
  • 申请和释放一段连续的空间时,使用的是 new[ ] 和 delete[ ]

new/delete操作自定义类型

 

class Test
{
  public:
  Test()
       : _data(0)
    {
      cout<<"Test():"<<this<<endl;
    }
  ~Test()
    {
      cout<<"~Test():"<<this<<endl;
    }
  private:
      int _data;
};

int main()
{
   // 申请单个Test类型的空间
   Test* p1 = (Test*)malloc(sizeof(Test));
   free(p1);

   // 申请10个连续Test类型的空间    
   Test* p2 = (Test*)malloc(sizoef(Test) * 10);
   free(p2);

   // 申请单个Test类型的对象
   Test* p3 = new Test;
   delete p3;

   // 申请10个连续的Test类型的对象
   Test* p4 = new Test[10];
   delete[] p4;
}
  • 在申请自定义类型的空间时,new 会调用构造函数,delete 会调用析构函数,而 malloc 和 free 不会调用对应的构造和析构函数
  • Test* p1 = (Test*)malloc(sizeof(Test));
    
    Test* p3 = new Test;

    在ANSI C标准中,malloc() 返回值类型是 void* ,malloc 并不知道返回的类型,所以需要用户自己定义,所以在使用时就要进行强制类型转换。  而 new 不需要进行强制类型转换,在开辟完空间后,它会调用构造函数完成对象的构造。

new/delete执行原理

内置类型

内置类型的空间开辟,malloc free 与 new delete 基本一致,不同之处在于

  • new/delete申请单个元素空间,new[]/delete[]申请连续空间
  • malloc 在申请空间失败返回NULL指针,而new申请失败时,会抛出异常

自定义类型

new的原理

  • 申请空间:调用 operator new 函数
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)//size:new之后所跟类型的字节数
        {       // try to allocate size bytes
        void *p;
        while ((p = malloc(size)) == 0)//返回失败
                if (_callnewh(size) == 0)//检测用户是否提供内存空间不足的应对方式
                {       // report no memory
                        // 如果申请失败,就会抛出 bad_alloc 类型异常
                        _THROW_NCEE(_XSTD bad_alloc, );
                }

        return (p);//成功直接返回
        }

operator new 函数内部使用 malloc 实现

  1. 申请成功,直接返回开辟的空间的首地址
  2. 申请失败,检测用户是否提供内存空间不足的应对方式。如果提供,执行用户所给的内存空间不足的解决方案,然后继续申请空间;如果不提供,就抛出异常
  • 调用相应的构造函数完成对象的构造

delete的原理

  • 在空间上调用析构函数,完成对象中资源的清理工作
  • 释放空间:调用 operator delete 函数
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 );

        __FINALLY
            _munlock(_HEAP_LOCK);  /* release other threads */
        __END_TRY_FINALLY

        return;
}

本质上是使用 free 来进行释放

 new  T[N]的原理

  • 申请空间:调用 operator new[ ] 函数
void * operator new[]( size_t cb )
{
    void *res = operator new(cb);

    RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));

    return res;
}

内部使用 operator new (size)函数实现,该函数还是用 malloc 来实现

  • 调用构造函数对N个对象进行初始化

delete [] 的原理

  • 调用N次析构函数,将对象中的资源清理干净(顺序:从后往前)
  • 调用 operator delete [ ] (void *p)
    void operator delete[](void * pUserData, int, const char *, int)
    {
        ::operator delete[](pUserData);
    }

    内部实现是 operator new (p),该函数内部还是用 free 来实现

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值