当前位置: 首页 > article >正文

02.02_111期_C++_数据内存分布笔记

operator new 和 operator delete是系统提供的全局函数
operator new是对malloc的封装
operator deleter是对free的封装

实际上在写出int* p2 = new int;这样的代码的时候,
 由于new是一个操作符,所以在编译的时候要转成对应的指令
 转成的指令就是operator new,这个operator new这个函数本质上和malloc是一样的
 
 写出ListNode* node1 = new ListNode(1);这样的代码的时候,
 new会申请空间,此时new转成的汇编指令中会先执行 operator new 和 再调用构造函数
 
 在写出int* p2 = new int[10];这样的代码的时候
 应该把new[10]看作是一个操作符,在编译的时候转成的汇编指令是operator new[]
 operator new[]会申请空间,其实现是operator new申请了10个int空间的函数
 
 写出ListNode* node2 = new ListNode[10];这样的代码的时候,
 new会申请空间,此时new转成的汇编指令是 operator new[] 
 此时的operator new[]实际上是先operator new 再调用构造函数,这样反复10次以后
 但是需要注意的是申请的空间是4 + 10 * sizeof(ListNode) 个字节的空间
 多开出来的4个字节的空间放的是对象个数,保证在使用delete[]进行释放时
 能够精准的释放之前申请的空间,delete[]在使用时不带参数
 之所以只有在释放自定义类型的空间时才会多申请4个字节(x86)
 这是因为需要对每个申请自定义类型的对象都调用析构函数
 如果这个类恰好是栈类,那么就需要把  在堆上申请的数组空间全部释放,
 那么释放多少次数组空间呢?只有通过这4个字节的空间中所存放的内容才能确定
 
 sizeof 和 strlen在底层上的不同
 sizeof 作为一个操作符,在编译时就会转成一堆指令,
 将内置类型或自定义类型按照规则算出所占字节数
 strlen 在生成可执行文件以后,在运行过程中按照库函数的逻辑返回一个值
 所以这两者的实现阶段都是不一样的

    对于申请了多个自定义对象在堆区后,要释放这些自定义对象所申请的空间
    应该使用delete[]
 

下面这两行代码说明了,
 new在申请了一块空间来放Stack中的_a, _top, _capacity之后
 如果要释放,必须是先释放_a指向的那块申请的整型数组空间
 然后再释放pst指向的自定义类型的空间,
 也就是说  delete是先将类中申请的空间释放(调用析构函数)
                     再把这个类所占的空间进行释放

1 有关c++内存分配堆栈

        1.1 栈区主要存在局部变量和函数参数,其空间的管理由编译器自动完成,无需手动控制,堆区是自己申请的空间,在不需  要时需要手动释放

        1.2栈区先定义的变量放到栈底,地址高,后定义的变量放到栈顶,地址低,因此是向下生长的,堆区则相反

        1.3 频繁的申请空间和释放空间,容易造成内存碎片,甚至内存泄漏,栈区由于是自动管理,不存在此问题

        1.4 32位系统下,最大的访问内存空间为4G,

2

        2.1 堆大小受限于操作系统,而栈空间一般有系统直接分配

        2.2 频繁的申请空间和释放空间,容易造成内存碎片,甚至内存泄漏,栈区由于是自动管理,不存在此问题

        2.3 堆无法静态分配,只能动态分配

        2.4栈可以通过函数_alloca进行动态分配,不过注意,所分配空间不能通过free或delete进行释放

3 下面代码的运行结果

ClassA *pclassa=new ClassA[5];

delete pclassa;

申请对象数组,会调用构造函数5次,delete由于没有使用[],此时只会调用一次析构函数,但往往会引发程序崩溃

        4.1 new会申请空间,同时调用构造函数初始化对象,malloc只做一件事就是申请空间

        4.2 new/delete与malloc/free最大区别就在于是否会调用构造函数与析构函数

        4.3 new是保留字,不需要头文件,malloc是库函数,需要头文件malloc.h,只是平时这个头文件已经被其他头文件所包含了,用的时候很少单独引入,故错误

        4.4 new是操作符,malloc是函数

5 设已经有A,B,C,D4个类的定义,程序中A,B,C,D析构函数调用顺序为

C c;

void main()

{

  A*pa=new A();

  B b;

  static D d;

  delete pa;

}

全局变量和全局静态变量最先定义,局部静态变量之后定义,局部变量最后定义 

局部自定义类型最先析构,局部静态自定义类型之后析构,全局或全局静态自定义类型最后析构

6 下面程序的运行结果

char* p = new char[100];
delete p;

对于内置类型,并不存在构造函数和析构函数这一个环节,所以即使new char [100] 和 delete不匹配,也可以使用上述代码进行释放


http://www.kler.cn/a/229527.html

相关文章:

  • Java接口与抽象类
  • 好“云”来!盘点春节与云计算息息相关的那些事儿
  • JVM 性能调优 - 四种引用(4)
  • 【动态规划】【图论】【C++算法】1928规定时间内到达终点的最小花费
  • 如何在Linux中安装新版的Python软件
  • Linux死机排查方法——内存日志
  • synchronized内部工作原理
  • OpenFeign之@Headers注解
  • PYthon进阶--网页采集器(基于百度搜索的Python3爬虫程序)
  • 【防止重复提交】Redis + AOP + 注解的方式实现分布式锁
  • Nim游戏
  • 使用 IDEA 开发一个简单易用的 SDK
  • DevOps落地笔记-15|混沌工程:通过问题注入提高系统可靠性
  • re:从0开始的CSS学习之路 1. CSS语法规则
  • 数论:修改数列
  • Spring Data Envers 数据审计实战
  • 编码安全风险是什么,如何进行有效的防护
  • Spring boot 集成redis
  • centos | vscode | 更新迭代太快了吧!
  • No matching client found for package name ‘com.unity3d.player‘