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不匹配,也可以使用上述代码进行释放

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值