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++内存管理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Qt 实现画线笔锋效果详细原理及示例代码

    Qt 实现画线笔锋效果详细原理及示例代码

    这篇文章主要介绍了Qt 实现画线笔锋效果详细原理及示例代码。文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • C++开发在IOS环境下运行的LRUCache缓存功能

    C++开发在IOS环境下运行的LRUCache缓存功能

    本文着重介绍如何在XCODE中,通过C++开发在IOS环境下运行的缓存功能。算法基于LRU,最近最少使用,需要的朋友可以参考下
    2012-11-11
  • 浅析c语言中的内存

    浅析c语言中的内存

    在c++中,内存分为5个区,分别是栈区,堆区,自由存储区,全局/静态存储区和常量存储区.
    2017-09-09
  • C++实现生产者与消费者模式方式

    C++实现生产者与消费者模式方式

    多线程工作池示例:创建固定数量的工作线程,通过条件变量竞争任务队列,确保任务均匀分发,任务队列读写操作由互斥锁保护,避免竞争,使用`notify_one()`唤醒空闲线程,`notify_all()`停止时唤醒所有线程退出,适用于CPU/IO密集型任务
    2025-12-12
  • C++ 中 const和static readonly区别

    C++ 中 const和static readonly区别

    这篇文章主要介绍了C++ 中 const和static readonly区别的相关资料,需要的朋友可以参考下
    2017-05-05
  • 详解C语言中index()函数和rindex()函数的用法

    详解C语言中index()函数和rindex()函数的用法

    这篇文章主要介绍了C语言中index()函数和rndex()函数的用法,是C语言入门学习中的基础知识,要的朋友可以参考下
    2015-08-08
  • C++简单实现消息队列的示例代码

    C++简单实现消息队列的示例代码

    消息队列是一种应用间的通讯方式,消息发送后可以立即放回,由消息系统来确保消息的可靠传递,本文主要介绍了C++简单实现消息队列的示例代码,感兴趣的可以了解一下
    2025-11-11
  • C++虚继承的实现原理由内存布局开始讲起

    C++虚继承的实现原理由内存布局开始讲起

    为了解决多继承时的命名冲突和冗余数据问题,C++提出了虚继承,使得在派生类中只保留一份间接基类的成员,下面我们从内存布局看看虚继承的实现原理
    2022-06-06
  • C语言中枚举与联合体的使用方法(enum union)

    C语言中枚举与联合体的使用方法(enum union)

    枚举的意思就是列举,将每一个可能的取值都进行一一列举,下面这篇文章主要给大家介绍了关于C语言中枚举与联合体的使用方法,需要的朋友可以参考下
    2021-09-09
  • C++实现LeetCode(199.二叉树的右侧视图)

    C++实现LeetCode(199.二叉树的右侧视图)

    这篇文章主要介绍了C++实现LeetCode(199.二叉树的右侧视图),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08

最新评论