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来释放空间

相关推荐
逆小舟1 小时前
【C/C++】指针
c语言·c++·笔记·学习
江公望1 小时前
Qt QtConcurrent使用入门浅解
c++·qt·qml
我是华为OD~HR~栗栗呀1 小时前
23届考研-Java面经(华为OD)
java·c++·python·华为od·华为·面试
爱吃喵的鲤鱼1 小时前
仿mudou——Connection模块(连接管理)
linux·运维·服务器·开发语言·网络·c++
郝学胜-神的一滴2 小时前
使用Linux的read和write系统函数操作文件
linux·服务器·开发语言·数据库·c++·程序人生·软件工程
2301_803554522 小时前
C++联合体(Union)详解:与结构体的区别、联系与深度解析
java·c++·算法
pu_taoc2 小时前
深入剖析:基于epoll与主从Reactor模型的高性能服务器设计与实现
服务器·c语言·c++·vscode
初圣魔门首席弟子3 小时前
c++ bug 函数定义和声明不一致导致出bug
开发语言·c++·bug
bkspiderx3 小时前
C++设计模式之行为型模式:中介者模式(Mediator)
c++·设计模式·中介者模式
敢敢J的憨憨L4 小时前
GPTL(General Purpose Timing Library)使用教程
java·服务器·前端·c++·轻量级计时工具库