我是靠谱客的博主 孤独皮皮虾,最近开发中收集的这篇文章主要介绍new / delete与malloc / free的异同及实现原理前言一、new和delete是如何实现的?二、new/delete和malloc/free的区别三、delete p、delete [] p、allocator都有什么作用?四、delete和delete[]区别?五、malloc申请的存储空间能用delete释放吗六、malloc与free的实现原理?总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 前言
  • 一、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的实现原理?总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部