概述
文章目录
- 前言
- 一、new和delete是如何实现的?
- 二、new/delete和malloc/free的区别
- 三、delete p、delete [] p、allocator都有什么作用?
- 四、delete和delete[]区别?
- 五、malloc申请的存储空间能用delete释放吗
- 六、malloc与free的实现原理?
- malloc函数
- calloc函数
- realloc函数
- 总结
前言
早餐店的老板问我要点什么,我说我要肆意妄为,志得意满,要梨花带雨和人见人爱,开个玩笑,我已经长大了,我要两根油条和一份豆浆。
一、new和delete是如何实现的?
new的实现过程是:
1、new简单类型直接调用operator new分配内存;
2、对于复杂结构:首先调用名为operator new的标准库函数,分配内存,接下来调用该类型对象的构造函数,最后返回指向新分配并构造后的对象的指针
3、对于简单类型,new[]计算好大小后调用operator new;
4、对于复杂数据结构,new[]先调用operator new[]分配内存,然后在p的前四个字节写入数组大小n,然后调用n次构造函数,针对复杂类型,new[]会额外存储数组大小;
delete的实现过程:
1、delete简单数据类型默认只是调用free函数;复杂数据类型先调用析构函数再调用operator delete 释放该对象所占内存;
2、针对简单类型,delete和delete[]等同。假设指针p指向new[]分配的内存。因为要4字节存储数组大小,实际分配的内存地址为[p-4],系统记录的也是这个地址。delete[]实际释放的就是p-4指向的内存。而delete会直接释放p指向的内存,这个内存根本没有被系统记录,所以会崩溃。
3、需要在new []一个对象数组时,需要保存数组的维度,C++的做法是在分配数组空间时多分配了4个字节的大小,专门保存数组的大小,在delete []时就可以取出这个保存的数,就知道了需要调用析构函数多少次了。
二、new/delete和malloc/free的区别
1、new/delete是C++运算符,支持重载,malloc/free是C/C++语言标准库函数,支持覆盖。
2、new自动计算要分配的空间大小,malloc需手工计算。
3、new是类型安全的,malloc不是。例如:
int*p=new float[2];//编译错误
int*p=(int*)malloc(2*sizeof(double));//编译无错误
4、new调用名为operator new的标准库函数分配足够空间并调用相关对象的构造函数,delete对指针所指对象运行适当的析构函数;然后通过调用名为operator delete的标准库函数释放该对象所用内存。后者均没有相关调用。
5、new是封装了malloc,直接free不会报错,但是这只是释放内存,而不会析构对象。
6、malloc、free需要库文件支持,new/delete需要编译器支持。
7、malloc和free返回的是void类型指针(必须进行类型转换),new和delete返回的是具体类型指针。
8、new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。
三、delete p、delete [] p、allocator都有什么作用?
1、动态数组管理new一个数组时,[]中必须是一个整数,但是不一定是常量整数,普通数组必须是一个常量整数;
2、new动态数组返回的并不是数组类型,而是一个元素类型的指针;
3、delete[]时,数组中的元素按逆序的顺序进行销毁;
4、new在内存分配上面有一些局限性,new的机制是将内存分配和对象构造组合在一起,同样的,delete也是将对象析构和内存释放组合在一起的。allocator将这两部分分开进行,allocator申请一部分内存,不进行初始化对象,只有当需要的时候才进行初始化操作。
四、delete和delete[]区别?
delete只会调用一次析构函数。
delete[]会调用数组中每个元素的析构函数。
五、malloc申请的存储空间能用delete释放吗
1、不能,malloc /free主要为了兼容C,new和delete完全可以取代malloc /free的。malloc /free的操作对象都是必须明确大小的,而且不能用在动态类上。
2、new和delete会自动进行类型检查和大小,malloc/free不能执行构造函数与析构函数,所以动态对象它是不行的。
3、当然从理论上说使用malloc申请的内存是可以通过delete释放的。不过一般不这样写的。而且也不能保证每个C++程序运行时都能正常。
六、malloc与free的实现原理?
1、在标准C库中,提供了malloc/free函数分配释放内存,这两个函数底层是由brk、mmap、,munmap这些系统调用实现的;
2、brk是将数据段(.data)的最高地址指针_edata往高地址推,mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存。这两种方式分配的都是虚拟内存,没有分配物理内存。在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系;
3、malloc小于128k的内存,使用brk分配内存,将_edata往高地址推;malloc大于128k的内存,使用mmap分配内存,在堆和栈之间找一块空闲内存分配;brk分配的内存需要等到高地址内存释放以后才能释放,而mmap分配的内存可以单独释放。当最高地址空间的空闲内存超过128K(可由M_TRIM_THRESHOLD选项调节)时,执行内存紧缩操作(trim)。在上一个步骤free的时候,发现最高地址空闲内存超过128K,于是内存紧缩。
4、malloc是从堆里面申请内存,也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。
malloc函数
void*malloc(unsignedintnum_size);
intp=malloc(20sizeof(int));申请20个int类型的空间;
calloc函数
void*calloc(size_tn,size_tsize);
int*p=calloc(20,sizeof(int));
省去了人为空间计算;malloc申请的空间的值是随机初始化的,calloc申请的空间的值是初始化为0的。
realloc函数
voidrealloc(void*p,size_tnew_size);
给动态分配的空间分配额外的空间,用于扩充容量。
总结
new / delete与malloc / free都可用于内存的动态申请和释放。但要注意他们之间的差异。
最后
以上就是孤独皮皮虾为你收集整理的new / delete与malloc / free的异同及实现原理前言一、new和delete是如何实现的?二、new/delete和malloc/free的区别三、delete p、delete [] p、allocator都有什么作用?四、delete和delete[]区别?五、malloc申请的存储空间能用delete释放吗六、malloc与free的实现原理?总结的全部内容,希望文章能够帮你解决new / delete与malloc / free的异同及实现原理前言一、new和delete是如何实现的?二、new/delete和malloc/free的区别三、delete p、delete [] p、allocator都有什么作用?四、delete和delete[]区别?五、malloc申请的存储空间能用delete释放吗六、malloc与free的实现原理?总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复