前言

在学习 C/C++ 的过程中,内存管理是绕不开的核心知识。很多初学者会感觉:

  • 栈、堆、静态区到底有什么区别?
  • malloc 和 new 到底差在哪?
  • 为什么 delete[] 不能写成 delete?
  • new 底层到底做了什么?
    如果这些问题没有形成完整体系,后面学习 STL、智能指针、内存池、操作系统时会越来越混乱。这篇文章将系统梳理整个知识链路,帮助你真正建立对内存管理的整体认知。

一、程序运行时的内存分布

一个 C/C++ 程序运行后,内存并不是随便使用的,而是被划分为不同区域。
通常我们会接触到以下几个区域:
在这里插入图片描述

1.1 栈(Stack)

栈主要存储:局部变量;函数参数;返回值
特点:由系统自动管理;生命周期随函数结束而结束,向下增长,速度快

void Test()
{
    int a = 10;
}
//这里的 a 就在栈上。

1.2 堆(Heap)

堆用于动态内存申请:

int* p = (int*)malloc(sizeof(int));

特点:由程序员手动管理;需要 free/delete;生命周期由程序员决定;向上增长;灵活但容易泄漏

1.3 数据段(静态区)

用于存储:全局变量;static 静态变量

int globalVar = 1;
static int staticVar = 1;

1.4 代码段(常量区)

存储:可执行代码;字符串常量;const 常量

const char* str = "hello";
//字符串 "hello" 位于常量区。

二、理解变量“本身”和“指向内容

这是初学者最容易混淆的地方。来看经典例子:

char arr[] = "abcd";
const char* p = "abcd";

很多人以为它们一样,其实完全不同。

char arr[] = "abcd";
const char* p = "abcd";
  • arr 是数组,数组本身在栈上,“abcd” 被拷贝到数组中。所以arr 在栈;arr中的字符也在栈。
  • p 是指针变量,指针本身在栈上,“abcd” 字符串常量在常量区。所以p 在栈;p指向的内容在常量区

三、C 语言动态内存管理

C 中主要使用四个函数:malloc;calloc;realloc;free。

3.1 malloc

申请指定大小内存:

int* p = (int*)malloc(sizeof(int));

特点:只申请空间;不初始化,因此里面是随机值。

3.2 calloc

int* p = (int*)calloc(4, sizeof(int));

特点:申请多个元素空间;自动初始化为 0。相当于:malloc + memset(0)。

3.3 realloc

用于扩容:

p = (int*)realloc(p, sizeof(int) * 10);

分别是原地扩容和异地扩容。

3.4 free

释放动态内存:

free(p);
//free 后不要继续使用指针
p = NULL;

四、C++ 为什么引入 new/delete

虽然 C 的 malloc/free 能用,但存在很多问题:

  • 需要手动计算大小;
  • 返回值需要强转;
  • 无法自动初始化对象;
  • 无法调用构造函数/析构函数;
    于是 C++ 引入:new和delete。

4.1new/delete 基本使用

//单对象
int* p = new int(10);
delete p;
//对象数组
int* arr = new int[10];
delete[] arr;

注意:new[] 必须对应 delete[]

4.2new/delete 与 malloc/free 最大区别

核心区别:malloc/free 只管理内存;new/delete 既管理内存,也管理对象。

1.malloc/free 不调用构造析构;A* p = (A*)malloc(sizeof(A));;这里只是开空间。对象并没有真正构造。

2.new/delete 会调用构造析构;A* p = new A(10);;A* p = new A(10);这里会申请空间和调用构造函数。
delete时会调用析构函数和释放空间。

4.3new[] 和 delete[] 为什么必须匹配

new[]:A* arr = new A[3];底层会:申请3个对象空间并且调用3次构造函数
delete[]:delete[] arr;调用3次析构函数并且释放空间

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐