首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

【C++】内存管理

  • 25-02-17 11:01
  • 3513
  • 13767
blog.csdn.net

【C++】内存管理

前言:

这里的内存管理会跟C语言的进行区分比较,注意两者的区别。

一、内存区域划分

  • 栈区:由编译器自动分配和释放,存放函数的参数值、非静态局部变量、返回值等,栈是向下增长的。
  • 堆区:用于动态内存分配,由程序员手动申请和释放。若不及时释放,会导致内存泄漏,堆是可以向上增长的。
  • 全局/静态区(数据段):存放全局变量和静态变量,程序开始时分配内存,结束时释放内存。
  • 代码段:可执行的代码、只读常量。

在这里插入图片描述

二、C语言内存管理方式(与C++区分)

  • malloc函数:函数原型为 viod malloc(size_t size),用于分配指定字节数的连续内存空间*。(malloc函数不初始化)
  • calloc函数:函数原型为 void*calloc(size_t num,size_t size) ,用于分配指定数量和大小的内存空间,并初始化为0。
  • relloc函数:函数原型为 void realloc (void ptr, size_t size)** ,用于调整已分配内存空间的大小 。
  • free函数:函数原型为 void free (void ptr)* ,用于释放动态分配的内存空间。
void Test ()
{
    int* p2 = (int*)calloc(4, sizeof (int));
    int* p3 = (int*)realloc(p2, sizeof(int)*10);
    free(p3 );
    p3=NULL;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

三、C++内存管理方式

C++内存管理通过 new和delete 操作符进行动态内存管理。

3.1 new/delete操作内置类型

  • 申请和释放单个元素的空间,使用new和delete操作符,
  • 申请和释放连续的空间,使用new[]和delete[],new在申请空间失败时会抛出异常。

示例:

在这里插入图片描述

3.2 new和delete操作自定义类型

在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc和free不会。

代码示例:

class A
{
    public:
    A(int a = 0)
        : _a(a)
        {
            cout << "A():" << this << endl;
        }
    ~A()
    {
        cout << "~A():" << this << endl;
    }
    private:
    int _a;
};

int main()
{
    // new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数
    //执行的时候就能看到

    A* p1 = (A*)malloc(sizeof(A));
    A* p2 = new A(1);
    free(p1);
    delete p2;


    // 内置类型是几乎是一样的
    //这一块的反汇编语言(vs2022):
    int* p3 = (int*)malloc(sizeof(int)); // C

    00007FF679842889  mov         ecx,4  
    00007FF67984288E  call        qword ptr [__imp_malloc (07FF679854488h)]  
    00007FF679842894  mov         qword ptr [p3],rax 

    int* p4 = new int;

    00007FF6798428B4  mov         rcx,qword ptr [p3]  
    00007FF6798428B8  call        qword ptr [__imp_free (07FF679854490h)]  
    00007FF6798428BE  nop  
   
    free(p3);
    delete p4;




}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

四、operator new与operator delete 函数

4.1 operator new 与operator delete函数

  • new和delete是用户进行动态内存申请和释放的操作符,

  • operator new和operator delete是系统提供的全局函数,

  • operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

4.2 new和delete的实现原理

内置类型与malloc/free基本类似

自定义类型:

  • new的原理:调用operator new 函数申请空间,在申请的空间上执行构造函数,完成对象的构造。
  • delete函数的原理:在空间上执行析构函数,完成对象中资源的清理工作,调用重载(operator delete)释放对象的空间。
  • new T[ N ]/delete T[ N ]的原理:调用operator new[]/operator delete[] 函数,在operator new[]/operator delete[] 中实际调用operator new/operator delete[] 函数完成N个对象空间的申请/释放,在申请的空间上执行N次构造函数/析构函数

基本函数:

// 全局默认的 operator new 和 operator delete
void* operator new(size_t size);        // 分配 size 字节的内存
void operator delete(void* ptr) noexcept; // 释放 ptr 指向的内存

// 数组版本(通常不建议直接使用)
void* operator new[](size_t size);
void operator delete[](void* ptr) noexcept;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

代码示例:

int main()
{
    // 申请空间+构造函数
    A* p2 = new A(10);
    A* p3 = new A[5];

    // 析构函数 + 释放空间
    delete p2;
    delete[] p3;

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

五、placement new(定位new表达式 )

概念:在已分配的原始内存空间中调用构造函数初始化一个对象

使用格式:

new (place_address) type
new (place_address) type(initializer-list)    
  • 1
  • 2

place_address必须是一个指针,initializer-list是类型的初始化列表

应用场景:

  • 内存池:预先分配大块内存,避免频繁调用分配器
  • 性能优化:在栈或静态内存上构造对象,减少堆碎片
  • 低级内存操作:如实现自定义容器(如std::vector的扩容机制)

六、C和C++内存管理的区别

区别malloc、free、new、delete:

  • malloc和free是函数,new和delete是操作符

  • malloc申请的空间不会初始化,new可以初始化

  • malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可, 如果是多个对象,[]中指定对象个数即可

  • malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型

  • malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需 要捕获异常

  • 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理释放

注:本文转载自blog.csdn.net的潘潘潘潘潘潘潘潘潘潘潘潘的文章"https://blog.csdn.net/2401_84538476/article/details/145445904"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

106
编程语言
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top