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

相关推荐
Tisfy3 分钟前
VSCode Docker(Code Server)首次调试C++长时间下载debuginfo问题
c++·vscode·docker
读书札记202210 分钟前
C++ switch..case语句中变量跨域问题探讨及解决方法
开发语言·c++
努力努力再努力wz17 分钟前
【Redis入门系列】Redis基础命令详解:从客户端连接到数据读写、key 管理与过期机制
c语言·开发语言·数据结构·数据库·c++·redis·缓存
Peter·Pan爱编程21 分钟前
输入输出:iostream 为什么不是 printf 的替代品
c++·输入输出·c++基础·iostream
代码村新手31 分钟前
C++-模板进阶
开发语言·c++
Shadow(⊙o⊙)34 分钟前
qt中自定义槽函数 内部继承逻辑、GUI+CLI协同1.0
开发语言·前端·c++·qt
雪度娃娃37 分钟前
行为型设计模式——职责链模式
c++·设计模式·责任链模式
·心猿意码·1 小时前
OCCT源码解析(二):NCollection解析
数据结构·c++
进击的荆棘1 小时前
C++起始之路——C++11(下)
开发语言·c++·c++11·lambda
许长安1 小时前
C++ 原子变量与内存序:从std::atomic到release/acquire
开发语言·数据结构·c++·经验分享·笔记