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

相关推荐
双叶83616 分钟前
(C++)学生管理系统(正式版)(map数组的应用)(string应用)(引用)(文件储存的应用)(C++教学)(C++项目)
c语言·开发语言·数据结构·c++
源代码•宸30 分钟前
C++高频知识点(二)
开发语言·c++·经验分享
jyan_敬言2 小时前
【C++】string类(二)相关接口介绍及其使用
android·开发语言·c++·青少年编程·visual studio
liulilittle2 小时前
SNIProxy 轻量级匿名CDN代理架构与实现
开发语言·网络·c++·网关·架构·cdn·通信
tan77º3 小时前
【Linux网络编程】Socket - UDP
linux·服务器·网络·c++·udp
GiraKoo3 小时前
【GiraKoo】C++14的新特性
c++
悠悠小茉莉4 小时前
Win11 安装 Visual Studio(保姆教程 - 更新至2025.07)
c++·ide·vscode·python·visualstudio·visual studio
坏柠4 小时前
C++ Qt 基础教程:信号与槽机制详解及 QPushButton 实战
c++·qt
泽02024 小时前
C++之红黑树认识与实现
java·c++·rpc
岁忧5 小时前
(LeetCode 每日一题) 1865. 找出和为指定值的下标对 (哈希表)
java·c++·算法·leetcode·go·散列表