C/C++ 内存管理详解:从内存分布到 new/delete 原理解析

 更新时间:2026年05月22日 10:35:06   作者:是dooo啊  
本文给大家介绍C/C++ 内存管理详解:从内存分布到 new/delete 原理解析,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

在 C++ 中,内存管理是一个核心概念,涉及到如何有效地使用内存资源。C++ 内存管理主要包括内存分配和内存释放两个方面,主要通过 new 和 delete 操作符来实现。下面我们将详细探讨 C++ 中的内存管理,包括内存的分布、new 和 delete 的工作原理以及一些高级话题,如智能指针的使用。

前言

在学习 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次析构函数并且释放空间

到此这篇关于C/C++ 内存管理详解:从内存分布到 new/delete 原理解析的文章就介绍到这了,更多相关C++内存管理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++实现趣味扫雷游戏

    C++实现趣味扫雷游戏

    这篇文章主要为大家详细介绍了C++实现趣味扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C++中I/O模型之select模型实例

    C++中I/O模型之select模型实例

    这篇文章主要介绍了C++中I/O模型的select模型,实例讲述了I/O模型的用法,具有一定的参考借鉴价值,需要的朋友可以参考下
    2014-10-10
  • Visual Studio Code 配置C、C++ 文件debug调试环境的详细过程

    Visual Studio Code 配置C、C++ 文件debug调试环境的详细过程

    这篇文章主要介绍了Visual Studio Code 配置C、C++ 文件debug调试环境,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • C++获取指定目录下的所有文件

    C++获取指定目录下的所有文件

    这篇文章主要为大家详细介绍了C++获取指定目录下所有文件的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • C语言中有哪些字符处理函数你知道吗

    C语言中有哪些字符处理函数你知道吗

    这篇文章主要为大家详细介绍了C语言字符处理函数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C语言数据结构之单链表的实现

    C语言数据结构之单链表的实现

    链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。本文将用C语言实现单链表,需要的可以参考一下
    2022-06-06
  • C语言读取BMP图像数据的源码

    C语言读取BMP图像数据的源码

    这篇文章主要介绍了C语言读取BMP图像数据的源码,需要的朋友可以参考下
    2013-03-03
  • C语言学生成绩管理系统课程设计

    C语言学生成绩管理系统课程设计

    这篇文章主要为大家详细介绍了C语言学生成绩管理系统课程设计,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • C语言宏定义的扩展定义讲解

    C语言宏定义的扩展定义讲解

    这篇文章主要介绍了C语言宏定义的扩展,宏定义是C语言提供的三种预处理功能的其中一种,这三种预处理包括:宏定义、文件包含、条件编译
    2022-12-12
  • Qt实现简易毛玻璃效果的示例代码

    Qt实现简易毛玻璃效果的示例代码

    这篇文章主要介绍了Qt如何利用模糊功能实现简易的毛玻璃效果,并且鼠标可以移动无边框窗口,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-06-06

最新评论