C++内存管理(区别C语言)深度对比

07-21 1264阅读

欢迎来到我的Blog,点击关注哦💕

前言

前面已经介绍了类和对象,对C++面向对象编程已经有了全面认识,接下来要学习对语言学习比较重要的是对内存的管理。

一、内存的分区

  1. 代码区:存放程序的机器指令,通常是可共享的,并且通常为只读的,以防止程序意外修改自身的代码。
  2. 全局/静态存储区:存放全局变量和静态变量,这些变量在程序的整个生命周期内都存在。
  3. 堆区:用于动态分配内存,程序运行时根据需要通过malloc、calloc、realloc等函数在堆区中分配内存空间。
  4. 栈区:存放函数的局部变量和函数调用的参数,由编译器自动管理,遵循后进先出的原则。
  5. 常量区:存放常量数据,如字符串字面量,这些数据在程序运行期间不可修改。
  6. 代码区:存放程序的二进制代码,是程序执行指令的存储空间。

C++内存管理(区别C语言)深度对比

二、C语言中的内存管理(参考)

  • malloc函数用于动态分配指定大小的内存空间,并返回指向该内存的指针。如果分配成功,返回非NULL指针;否则返回NULL。
  • calloc函数除了分配内存外,还会将分配的内存初始化为零。
  • realloc函数用于调整已分配内存的大小,可能会移动内存块以适应新的大小要求。
  • free函数用于释放之前通过动态内存分配函数分配的内存空间

    三、C++中的内存管理

    C++内存分配

    不同于C语言,C++有着自己独立动态内存开辟的方法:

    ​ 主要通过new和delete操作符来实现。new操作符用于分配单个对象或数组,而delete和delete[]分别用于释放这些对象或数组所占用的内存.

    下面是new和delete应用的实例:

     //动态申请一个int大小空间
    int* p0 = new int;
    //动态申请一个int大小空间并且初始化为0
    int* p1 = new int (0);
    //动态申请10个int大小空间
    int* p2 = new int[10];
    //动态申请10个int大小空间并且初始化为0
    int* p3 = new int[10] {0};
    delete p0;
    delete p1;
    delete[] p2;
    delete[] p3; 
    

    注意

    1. 不要使用delete释放非new开辟的空间
    2. 不要使用delete释放同一块空间两次
    3. 如果使用new [ ] 开辟数组进行内存分配,应该使用delete [ ] 来释放
    4. 如果new对一个实体进行内存分配,应该使用delete(没有方括号)进行释放

    四、new 和 delete深度探索

    有关operator new 和operator delete

    operator new

    • operator new是一个特殊的操作符,用于动态分配内存。它与new操作符密切相关,但它们在语义上有所区分。

    • new操作符是一个高级操作符,它不仅分配内存,还自动调用对象的构造函数。

    • operator new仅负责分配内存,不涉及对象的构造。

    • operator new可以被重载,以便为特定的类或全局范围提供自定义的内存分配策略

    • operator new:该函数实际通过``malloc来申请空间,当malloc`申请空间成功时直接返回

    • 申请空间失败, 尝试执行空 间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。

      通俗的讲 ,new 不仅仅可以进行空间开辟,针对自定义类型会调用其构造函数,而new也是调用重载(operator new),进行内存的分配,然而 operator new 进行内存分配是通过malloc进行实现的,这正是区别于C语言的其中一点。

      关于时间类和汇编语言:

      class Date
      {
      public:
      	Date(int year = 1,int month = 1,int day = 1)
      		:_year(year)
      		,_month(month)
      		,_day(day)
      	{}
      	~Date()
      	{
      		_year = 0;
      		_month = 0;
      		_day = 0;
      	}
      private:
      	int _year = 1;
      	int _month = 1;
      	int _day = 1;
      };
      	Date* d1 = new Date;
      00007FF62A0D19FC  mov         ecx,0Ch  
      00007FF62A0D1A01  call        operator new (07FF62A0D103Ch)  。//调用operator new内存分配
      00007FF62A0D1A06  mov         qword ptr [rbp+108h],rax  
      00007FF62A0D1A0D  cmp         qword ptr [rbp+108h],0  
      00007FF62A0D1A15  je          main+5Dh (07FF62A0D1A3Dh)  
      00007FF62A0D1A17  mov         r9d,1  
      00007FF62A0D1A1D  mov         r8d,1  
      00007FF62A0D1A23  mov         edx,1  
      00007FF62A0D1A28  mov         rcx,qword ptr [rbp+108h]  
      00007FF62A0D1A2F  call        Date::Date (07FF62A0D13D4h)    // 调用构造函数
      00007FF62A0D1A34  mov         qword ptr [rbp+118h],rax  
      00007FF62A0D1A3B  jmp         main+68h (07FF62A0D1A48h)  
      00007FF62A0D1A3D  mov         qword ptr [rbp+118h],0  
      00007FF62A0D1A48  mov         rax,qword ptr [rbp+118h]  
      00007FF62A0D1A4F  mov         qword ptr [rbp+0E8h],rax  
      00007FF62A0D1A56  mov         rax,qword ptr [rbp+0E8h]  
      00007FF62A0D1A5D  mov         qword ptr [d1],rax 
      

      operator delete

      • operator delete 是一个全局函数,用于释放之前通过 operator new 分配的内存。
      • 它是 new 操作符的逆运算,负责在内存释放时执行必要的清理工作。
      • operator delete 通常在 delete 表达式中被隐式调用,用于释放单个对象或对象数组的内存
      • 在空间上执行析构函数,完成对象中资源的清理工作
      • 调用operator delete函数释放对象的空间(通过free)
        00B72150	push	ebp	已用时间
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]