C++基础入门:内存管理

◆博主名称:少司府

欢迎来到少司府的博客☆*: .。. o(≧▽≦)o .。.:*☆

数据结构系列个人专栏:

初阶数据结构_少司府的博客-CSDN博客

C++基础个人专栏:

C++初阶_少司府的博客-CSDN博客

⭐名不显时心不朽,再挑灯火看文章

目录

[一、C/C++ 内存分布](#一、C/C++ 内存分布)

[1.1 例题引入](#1.1 例题引入)

[1.2 内存区域划分](#1.2 内存区域划分)

二、C++管理内存方式

[2.1 new和delete](#2.1 new和delete)

[2.1.1 对于内置类型](#2.1.1 对于内置类型)

[2.1.2 对于自定义类型](#2.1.2 对于自定义类型)

[2.2 operator new 和 operator delete 函数](#2.2 operator new 和 operator delete 函数)

三、new和delete的实现原理

[3.1 内置类型](#3.1 内置类型)

[3.2 自定义类型](#3.2 自定义类型)

[3.2.1 new的原理](#3.2.1 new的原理)

[3.2.2 delete的原理](#3.2.2 delete的原理)

[3.2.3 new T[N] 和 delete[] 的原理](#3.2.3 new T[N] 和 delete[] 的原理)

[3.3 实际空间结构](#3.3 实际空间结构)

四、定位new表达式


一、C/C++ 内存分布

1.1 例题引入

我们通过一道例题来引入讲解C/C++的内存分布:

cpp 复制代码
int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
 static int staticVar = 1;
 int localVar = 1;
 int num1[10] = { 1, 2, 3, 4 };
 char char2[] = "abcd";
 const char* pChar3 = "abcd";
 int* ptr1 = (int*)malloc(sizeof(int) * 4);
 int* ptr2 = (int*)calloc(4, sizeof(int));
 int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
 free(ptr1);
 free(ptr3);
}

如图,易知:

1)、glovalVar 是全局变量 ,存在静态区

2)、staticGlobalVar 是全局静态变量,存在静态区

3)、staticVar 是局部静态变量,存在静态区

4)、localVar 和 num1 存在函数开辟的栈帧空间里面

5)、char2 是栈上定义的数组,数组名及元素 *char 都存在栈上

6)、pchar3 在栈上定义,存在栈上;常量字符串存在常量区

7)、malloc、calloc、realloc 开辟的空间在

1.2 内存区域划分

如图,需要注意的是:

在32位下,虚拟空间是4G,指针是4个字节,(指针在内存中是编号,00000000 到 FFFFFFFF 刚好是2^32 个编号,也就是4G),堆的空间大概1.8G左右,栈大概8M。

在64位下,虚拟空间是2^32 * 4G ,指针是8个字节。

|--------------|----------------------------------------------------------|
| | 又叫堆栈,存放非静态局部变量/函数参数/返回值等等,栈是向下增长的。 |
| 内存映射段 | 高效的I/O映射方式,用于装载一个共享的动态内存库 。用户可使用系统接口创建共享共享内存,做进程间通信。 |
| | 用于程序运行时动态内存分配,堆是可以上增长的。 |
| 数据段(静态区) | 存储全局数据和静态数据。 |
| 代码段(常量区) | 可执行的代码/只读常量。 |

二、C++管理内存方式

2.1 new和delete

C++中使用new来申请空间,delete来释放空间。

2.1.1 对于内置类型

如图,delete删除的时候要和申请出来的类型一一对应。

2.1.2 对于自定义类型
cpp 复制代码
A* p1=new A(1,2); // new对于自定义类型,会自动调用构造函数,申请对象+初始化
A* p2=new A[3]; // 调用3次构造
A* p3=new A[3]{A{1,1},A{2,2},A{3,3}};
A* p4=new A[3]{{1,1},{2,2},{3,3}};
delete p1; // delete对于自定义类型,会自动调用析构函数
delete[] p2;
delete[] p3;
delete[] p4;

如图,对于自定义类型,new是 malloc+构造,delete是 析构+free

2.2 operator new 和 operator delete 函数

new 和 delete 是用户进行动态申请和释放的操作符,operator new 和 operator delete 是系统提供的全局函数,new在底层调用operator new 来申请空间,delete在底层调用operator delete来释放空间。

而operator new 的底层是malloc,operator delete 的底层是free。

三、new和delete的实现原理

3.1 内置类型

对于内置类型的空间,malloc/free 和 new/delete 基本类似区别在于:new 在申请空间失败会抛异常,malloc会返回NULL。

3.2 自定义类型
3.2.1 new的原理

1)、调用operator new 函数申请空间,申请失败就抛异常(operator new 调 malloc)

2)、在申请的空间上执行构造函数,完成对对象的构造

3.2.2 delete的原理

1)、在空间上执行析构函数,完成对象中资源的清理

2)、调用operator delete函数释放对象的空间

3.2.3 new T[N] 和 delete[] 的原理

同理,调N次构造或者析构

3.3 实际空间结构
cpp 复制代码
B* p2=new B[10]; // 假设A、B均为8字节,且B没有写析构
A* p3=new A[10];
delete p2;
delete p3; // error -> delete[] p3;
           // 释放位置不对

四、定位new表达式

定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象

cpp 复制代码
A* p2=(A*)operator new(sizeof(A));
new(p2)A(10); // placement new,定位new,对已开辟的空间显示调用构造函数
p2->~A(); // 显示调用析构
operator delete(p2);

使用场景:

定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如 果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。

本期的分享就到这里,如果觉得博主的文章比较对胃口的话,可以点一个小小的关注~

您的三连是我持续更新的动力~

相关推荐
鱼很腾apoc2 小时前
【学习篇】第17期 C++入门必看——类和对象全站最详篇
c语言·开发语言·学习·算法·青少年编程
Sakuyu434682 小时前
C语言基础(一)
c语言·开发语言
码农的神经元2 小时前
2026 MathorCup C 题实战复盘:从高血脂风险预警到 6 个月干预优化的建模思路与 Python 落地
c语言·开发语言·python
人道领域2 小时前
【黑马点评日记03】实战:Redis缓存穿透,缓存击穿,缓存雪崩全解析
java·开发语言·jvm·redis·spring·tomcat
阿拉金alakin2 小时前
深入理解 Java 线程池:核心参数、工作流程与常用创建方式
java·开发语言·java-ee
郝学胜-神的一滴2 小时前
从零起步:CMake基础入门与实战跨平台编译
c++·软件工程·软件构建·cmake
slandarer3 小时前
MATLAB | R2026a 更新了哪些有趣的新东西?
开发语言·数据库·matlab
早起傻一天~G3 小时前
vue2+element-UI上传图片封装
开发语言·javascript·ui
耿雨飞3 小时前
Python 后端开发技术博客专栏 | 第 03 篇 面向对象编程进阶 -- 从 SOLID 原则到 Python 特色 OOP
开发语言·python·面向对象·oop