C++——动态内存管理__C动态管理、new、delete

动态内存管理

C++中 malloc不调用构造函数,free 不调用析构函数。因此对象的资源依旧存在,只是对内存的空间进行申请,释放的。所以C++有自己的内存管理——new,delete。从而申请释放空间。

 申请的地址空间(new,malloc申请那样)就在堆那里。

局部变量就在栈那里。

局部变量的值在代码段。

例子:char a[]="asdf";     char a[]:在栈;"asdf":在代码段,因为它是字符常量。


 栈又叫堆栈,非静态局部变量/函数参数/返回值等等,栈是向下增长的。 

堆用于程序运行时动态内存分配,堆是可以上增长的。

数据段--存储全局数据和静态数据。 

代码段--可执行的代码/只读常量。 


C语言中动态内存管理方式:

空间申请:

void malloc(size_t num);

void calloc(size_t num,size_t size);        num是元素个数;size是单个元素大小

void* realloc(void* p,size_t size);        p:地址;size是字节数

空间释放:

free(void* p)   p:释放空间首地址

比较:

用的时候一定要free!!


C++语言中动态内存管理方式:

malloc/free:可以继续使用,但是一般不使用,因为只负责空间申请以及释放,不负责构造和销毁。

new/delete:申请和释放单个对象

new[ ] /delete[ ]:申请和释放一段连续的空间

注意:一定要匹配使用,否则就会资源泄漏!!!

 new:(是关键字)

	int* p1 = new int;   //单个int类型的空间    //不用强制转换
	int* p2 = new int(10);   //可以初始化  //初始化10

	int array[10];    //问:数组类型——int[10]   //名字拿掉剩下的    //问元素类型——int(整型)
	int* p3 = new int[10];  
	int* p4 = new int[10]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };  //初始化

这也看出了new 和 malloc 的区别。不判空,不传字节数,不强转,可以初始化,调用构造/析构函数。

malloc 只是申请与对象大小一样的空间,不进行构造空间;delete是对完整对象进行销毁,释放对象


delete:(是关键字)

int* p1 = new int;   //单个int类型的空间    //不用强制转换
int* p2 = new int(10);   //可以初始化  //初始化10

int array[10];    //问:数组类型——int[10]   //名字拿掉剩下的    //问元素类型——int(整型)
int* p3 = new int[10];  
int* p4 = new int[10]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };  //初始化

delete p1;
delete p2;
delete[] p3;
delete[] p4;

注:new 和 delete 一定要匹配使用


 类中的使用:

Date* p5=new Date (2019, 5, 16);  //调用了构造函数   
delete p5;

Date* p6 = new Date[10];  //所指空间 10个Date对象的空间
delete[] p6;

new所做的事情:

  • 申请空间   
  • 调用构造函数构造成完整的对象

delete做的事情:

  • 调用析构函数清理对象资源
  • 释放对象的内存空间

new T[N]:就是重复N次new操作

delete[ ]:就是重复deleteN次操作

 operator new与operator delete函数:

new底层实现就是调用operator new函数

new(字节数)——>循环调用 malloc函数

malloc 成功:返回空间首地址;malloc 失败(内存空间不足):执行用户定义的措施,没有措施就抛出异常。它是不会返回NULL。


delete底层实现就是调用operator delete函数

通过 free函数 来释放空间的。

内存池:

内存的申请很慢,容量也不够,内存池非常方便,申请效率快,没有额外空间的浪费,也就是提前申请一块内存空间,需要只用割下来一部分,就用;不够,继续给就好了。类似银行卡,需要就刷卡,没了打钱就好了。

 函数:

头文件:

#include<memory>    

allocator<对象>().allocate(1);      1:表示对象的个数

 void* operator new(size_t n) {      //将new 重载成创建内存池  
    void* p = nullptr;        
    p = allocator<ListNode>().allocate(1);        
    cout << "memory pool allocate" << endl;        
    return p;    
} 

 allocator<ListNode>().deallocate((ListNode*)p, 1);   内存池还回来。

 定位new表达式:

无意中写成malloc函数,而不是new,这时候可以在malloc创建的空间上执行构造函数,也就可以实现对象的new。

//pt现在指向的只不过是与Test对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行  

Test* pt = (Test*)malloc(sizeof(Test));      
new(pt) Test;  

// 注意:如果Test类的构造函数有参数时,此处需要传参

释放空间就delete 就好了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值