C++动态内存管理(比较C动态内存管理)

首先我们先了解一下内存:

这里写图片描述

C语言使用malloc/free动态管理内存空间,C++引入了new/delete,new[]/delete[]来动态管理内存。
介绍new/delete,new[]/delete[]之前我们先了解一下operator new,operator delete,operator new[],operator delete[]函数。

注:这些函数并没有重载new/delete表达式。

函数声明如下:
void* operator new(size_t size);
void operator delete(size_t size);
void* operator new[](size_t size);
void operator delete[](size_t size);

析:operator new/operator delete,operator new[]/operator delete[]是标准库函数,用法和malloc/free的用法一样,只负责分配/释放空间,但实际上operator new/operator delete只是malloc/free的一层封装。

new/delete:动态管理对象;
new[]/delete[]动态管理对象数组。

int* ptr1=new int;//动态分配4个字节的空间
delete ptr;
int* ptr2=new int(4);//动态内存分配4个字节空间并初始化
delete ptr2;
int* ptr3=new int[4];//动态内存分配16个字节空间
delete[];

1>,new/delete实际上做了什么事呢??
new:先调用operator new分配空间,再调用构造函数初始化空间。
delete:先调用析构函数清理对象,再调用operator delete释放空间。

这里写图片描述
这里写图片描述

2>,new[]/delete[]实际上做了什么事呢??
new[n]:调用operator new分配空间,再调用n次构造函数初始化对象。
delete[n]:调用n次析构函数清理对象,再调用operator delete释放空间。

这里写图片描述

为什么编译器会知道调用多少次构造函数,析构函数呢?
原来在new[ ]分配空间的时候会在头部多分配4个字节来存n,这样在调用new[]/delete[]时就知道调用几次构造函数和析构函数了。

new/delete,new[]/delete[]为什么要成对出现?
当new在开辟内置类型的空间时,不成对出现是可以的;但是当开辟非内置类型空间时,就要多开辟4个字节,这时如果不成对使用就会造成内存泄漏或者程序崩溃。
这里写图片描述

用宏模拟实现new[]/delete[]申请和释放数组

//DELETE_ARRAY参数中传n
#define NEW_ARRAY(ptr,type,n)                          
do{                             
ptr=(type*)operatornew(sizeof(type)*n);             
for (size_t i = 0; i <n;++i)                            
{                       
new(ptr+i)type;                     
}                                                       
} while (0);                                            


#define DELETE_ARRAY(ptr,type,n)                
do{                             
for (size_t i = 0; i < n; ++i)                          
{               
(ptr+i)->~String();                        
}                               
operator delete ptr;                                
} while (0);
//给DELETE_ARRAY中不传n
#define NEW_ARRAY(ptr,type,n)                           
do{                                                                             
ptr = (type*)operator new(sizeof(type)*n + 4);           //给n也分配空间
*(int*)ptr = n;                                             
ptr=(type*)((char*)ptr+4);                                  
for (size_t i = 0; i < n; ++i)                              
{                                                       
new(ptr + i)(type);                                 
}                                                           
} while (0);

#define DELETE_ARRAY(ptr,type)                              
do{                                                         
    size_t n = *((int*)ptr - 1);                            
    for (size_t i = 0; i < n; ++i)                              
    {                                                           
    (ptr + i)->~String();                                  
    }                                                           
    operator delete(char*(ptr - 4));                            
} while (0);

malloc/free和new/delete之间关系和差异
关系:都能进行动态内存管理。
差异:1>,malloc/free是标准的库函数, new/delete是操作符;
2>,malloc/free只是分配/释放内存 ,new/delete不仅分配/释放内存还调用构造函数初始化和析构函数清理;
3>,malloc/free手动计算类型大小,返回值void*,new/delete自动计算类型大小,返回对应类型的指针;
4>,malloc/free失败返回0, new/delete失败抛异常。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值