C/C++内存管理

1、C/C++内存分布

程序中需要存储一些数据,这些数据包括局部数据、静态数据和全局数据、常量数据、动态申请数据,程序会将内存区域划分多个部分,将不同的数据存放在相应的区域。如下图所示,其中栈是向下增长的,用于存储一些局部数据。堆是向上增长的,用于实现动态分配内存,也就是函数中的动态申请数据的部分。静态区也叫做数据段,函数中的静态数据和全局数据都是存储在这里。常量区也叫做代码段,用于存储程序中的常量数据和可执行的代码。

2、C语言中动态内存管理方式:malloc/calloc/realloc/free

那么他们之间的区别是什么呢?

1、malloc:

用于分配一块指定大小的内存,malloc分配的内存块的内容是未初始化的,即里面的值是随机的,如果分配成功则返回一个指向分配内存的指针,如果分配失败,则返回NULL

2、calloc

用于分配一块内存,并初始化为零,如果成功则返回一个指向分配内存的指针,如果失败则返回NULL

3、realloc

用于重新调整已经分配的内存块的大小,可能会在原位置扩展内存(如果原位置依然有空间可供使用),也可能会将其移动到新的位置并将原来的内容复制到新的内存位置上。如果成功,返回指向新的内存区域的指针,如果失败,返回NULL且不释放原内存块

3、C++内存管理方式

C++中使用new和delete操作符进行动态内存管理

1)对于内置类型

new/delete和malloc/free几乎是一样的

cpp 复制代码
void Test()
{
    //动态申请一个int类型的空间
    int* ptr4=new int;
    
    //动态申请一个int类型的空间并初始化为10
    int* ptr5=new int(10);

    //动态申请10个int类型的空间
    int* ptr6=new int[3];

    delete ptr4;
    delete ptr5;
    delete[] ptr6;
}

申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],注意要匹配起来进行使用

2)对于自定义类型

对于自定义类型new/delete除了开空间还会调用构造函数和析构函数,但是malloc/free不会

cpp 复制代码
class A
{
public:
    A(int a=0)
    :_a(a)
    {
        cout<<"A():"<<endl;
    }
    ~A()
    {
        cout<<"~A():"<<endl;
    }
private:
    int _a;
}

int main()
{
    A* p1=(A*)malloc(sizeof(A));
    A* p2=new A(1);
    free(p1);
    delete p2;
    
    A* p5=(A*)malloc(sizeof(A)*10);
    A* p6=new A[10];
    free(p5);
    delete[] p6;
}

4、operator new与operator delete函数

new和delete是用户进行动态内存申请和释放的操作符,operator new和operatordelete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

而operator new实际通过malloc来申请空间,当malloc申请空间成功时会直接返回,若申请失败则抛异常,operator delete是通过free来释放空间的

总结:

new/delete和malloc/free在使用时,对于申请内置类型的空间,二者区别并不大,只不过new/delete可以申请和释放单个元素的空间,也可以使用new[]/delete[]来申请连续的空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。

new/delete和malloc/free在使用时,对于申请自定义类型的空间区别较大,new会调用operator new函数来申请空间,再在申请的空间上执行构造函数来完成对象的构造。delete会在空间上执行析构函数完成对象中资源的清理工作,再调用operator delete函数释放对象的空间。new T[]和delete[]也是类似的,new T[]会先调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请,再在申请的空间上执行N次构造函数。delete[]是在释放的对象空间上执行N次析构函数,完成N个对象中的资源清理,再调用operator delete[]释放空间,实际也是调用operator delete来释放空间

相关推荐
招摇的一半月亮40 分钟前
P2242 公路维修问题
数据结构·c++·算法
f***01932 小时前
CC++链接数据库(MySQL)超级详细指南
c语言·数据库·c++
合方圆~小文2 小时前
球型摄像机作为现代监控系统的核心设备
java·数据库·c++·人工智能
椰萝Yerosius3 小时前
[题解]2024CCPC郑州站——Z-order Curve
c++·算法
滨HI06 小时前
C++ opencv简化轮廓
开发语言·c++·opencv
学习路上_write6 小时前
FREERTOS_互斥量_创建和使用
c语言·开发语言·c++·stm32·单片机·嵌入式硬件
闻缺陷则喜何志丹7 小时前
【SOSDP模板 容斥原理 逆向思考】3757. 有效子序列的数量|分数未知
c++·算法·力扣·容斥原理·sosdp·逆向思考
BestOrNothing_20158 小时前
一篇搞懂 C++ 重载:函数重载 + 运算符重载,从入门到会用(含 ++、<<、== 实战)
c++·函数重载·运算符重载·operator·前置后置++·重载与重写
2501_941144428 小时前
Python + C++ 异构微服务设计与优化
c++·python·微服务
程序猿编码8 小时前
PRINCE算法的密码生成器:原理与设计思路(C/C++代码实现)
c语言·网络·c++·算法·安全·prince