C++初阶篇----内存管理

目录

  • 引言
  • 1. 内存分布
  • 2.C动态内存管理方式:malloc/calloc/realloc/free
  • 3. C++动态内存管理:new和delete
    • 3.1内置类型
    • 3.2 自定义类型
  • 4.operator new与operator delete函数
    • 4.1 operator new 与operator delete函数
  • 5. new和delete的实现底层
    • 5.1 内置类型
    • 5.2 自定义类型

引言

什么是内存管理?以下便是一些内存管理的基础概念

1.内存分配(Memory Allocation): 内存分配是指操作系统或应用程序为程序执行和数据存储分配内存空间的过程。这可以通过动态分配和静态分配来实现。

静态分配: 在程序运行之前,编译器为程序的变量和数据分配固定的内存空间。这些分配在程序执行期间保持不变。

动态分配: 在程序运行时,使用动态内存分配函数(例如C++中的new和delete、C语言中的malloc和free)从堆中分配内存。这使得程序能够在运行时根据需要分配和释放内存。

2.内存释放(Memory Deallocation): 已分配的内存需要在不再需要的时候释放,以防止内存泄漏。动态内存分配后,需要负责释放这些内存。

3.碎片(Fragmentation): 内存碎片分为两类:外部碎片和内部碎片。外部碎片是指未分配的零散内存块,而内部碎片是指已分配内存块中未被使用的部分。

4.虚拟内存(Virtual Memory): 操作系统使用虚拟内存技术,允许程序使用比实际物理内存更大的内存空间。这通过将部分数据和代码存储在硬盘上的交换文件中来实现。

5.页表(Page Tables): 用于将虚拟地址映射到物理地址。页表允许操作系统在虚拟内存和物理内存之间进行映射。

6.内存保护: 操作系统通过设置合适的权限和访问规则,确保程序不能越权地访问其他程序或操作系统的内存空间。

7.内存管理单元(Memory Management Unit,MMU): 是计算机硬件的一部分,负责虚拟地址和物理地址之间的转换,以及内存访问的权限控制。

1. 内存分布

在这里插入图片描述

  1. 栈又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的
  2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口
    创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)
  3. 堆用于程序运行时动态内存分配,堆是可以上增长的。
  4. 数据段–存储全局数据和静态数据。
  5. 代码段–可执行的代码/只读常量。

2.C动态内存管理方式:malloc/calloc/realloc/free

他们的区别:
malloc:动态开辟,分配空间不初始化
calloc:分配空间并初始化为0
realloc:重新分配内存块

#include<stdlib.h>int main()
{int* p1 = (int*)malloc(sizeof(int));*p1 = 2;int* p2 = (int*)calloc(4, sizeof(int));int* p3 = (int*)realloc(p2, sizeof(int) * 2);free(p1);free(p3);return 0;
}

在这里插入图片描述
malloc的实现原理:
glibc中malloc实现原理

3. C++动态内存管理:new和delete

3.1内置类型

int main()
{//动态申请一个int类型int* p1 = new int;//动态申请一个int类型并初始化为10int* p2 = new int(10);//动态申请int数组int* p3 = new int[10];delete p1;delete p2;delete[] p3;
}

在这里插入图片描述

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用 new[]和delete[],注意:匹配起来使用

3.2 自定义类型

class A
{
private:int _a;
public:A(int a=2) :_a(a){cout << "A" << endl;}~A(){cout << "~A" << endl;}
};int main()
{A* p1 = new A;delete p1;A* p2 = new A[10];delete[] p2;return 0;
}

在这里插入图片描述

注意:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数

4.operator new与operator delete函数

4.1 operator new 与operator delete函数

operator new和operator delete 是 C++ 中用于动态分配内存和释放的函数。它是 C++ 中的运算符重载函数,用于在堆(heap)上动态分配内存存空间,并返回分配的内存地址。

在 C++ 中,当你需要动态分配内存时,你可以使用 new 运算符。new 运算符背后实际上调用了 operator new 函数来执行内存分配操作。

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

5. new和delete的实现底层

5.1 内置类型

前面已经提到过内置类型的应用
申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:
new/delete申请和释放的是单个元素的空间new[]和delete[]申请的是连续空间,而且new在申
请空间失败时会抛异常malloc会返回NULL

5.2 自定义类型

new的原理

  1. 调用operator new函数申请空间
  2. 在申请的空间上执行构造函数,完成对象的构造

delete的原理

  1. 在空间上执行析构函数,完成对象中资源的清理工作
  2. 调用operator delete函数释放对象的空间

new T[N]的原理

  1. 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
  2. 在申请的空间上执行N次构造函数

delete[]的原理

1. 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
2. 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释

放空间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/577895.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis 特性,为什么要用Redis,Redis到底是多线程还是单线程

一、Redis介绍 Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务&#xff0c;是一个开源的&#xff0c;使用C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。 二、特性(为什么要用Redis&#x…

如何注册谷歌邮箱gmail

不知道大家在工作生活中有没有需要用到谷歌邮箱的地方&#xff0c;但是最近我就用到了它。因为注册ChatGPT的事&#xff0c;用了outlook&#xff0c;hotmail邮箱注册的gpt账号都被封了&#xff0c;然后通过各方面的了解&#xff0c;发现谷歌的邮箱是没有问题的&#xff0c;不会…

基于springboot的人事管理系统

人事管理系统 摘 要 人事管理系统理工作是一种繁琐的&#xff0c;务求准确迅速的信息检索工作。随着计算机信息技术的飞速发展&#xff0c;人类进入信息时代&#xff0c;社会的竞争越来越激烈&#xff0c;人事就越显示出其不可或缺性&#xff0c;成为学校一个非常重要的模块。…

小狐狸JSON-RPC:钱包连接,断开连接,监听地址改变

detect-metamask 创建连接&#xff0c;并监听钱包切换 一、连接钱包&#xff0c;切换地址&#xff08;监听地址切换&#xff09;&#xff0c;断开连接 使用npm安装 metamask/detect-provider在您的项目目录中&#xff1a; npm i metamask/detect-providerimport detectEthereu…

36-递归与迭代

36-1 用递归和迭代解决问题 1、求n的阶乘 公式&#xff1a; n!123...(n-1)n。用递归方式定义&#xff1a;0!1&#xff0c;n!(n-1)!n。 代码1&#xff1a; 我们先回忆一下之前用循环怎么实现的吧 非递归&#xff0c;也可称迭代&#xff1a; int main() {int n 0;scanf(&q…

书生浦语训练营2期-第一节课笔记

笔记总结: 了解大模型的发展方向、本质、以及新一代数据清洗过滤技术、从模型到应用的典型流程、获取数据集的网站、不同微调方式的使用场景和训练数据是什么&#xff0c;以及预训练和微调在训练优势、通信/计算调度、显存管理上的区别。 收获&#xff1a; 理清了预训练和微调…

Laya1.8.4 UI长按选择对应位置释放技能

需求&#xff1a; 需要实现拖拽摇杆选择技能释放位置&#xff0c;释放技能。 原理&#xff1a;首先拆分需求&#xff0c;分为两部分&#xff0c;UI部分和场景部分&#xff0c;UI部分需要实现长按效果&#xff0c;长按后又要有拖动效果&#xff0c;将官方文档的示例代码改了改…

[机器学习]练习KNN算法-曼哈顿距离

曼哈顿距离(Manhattan distance) 曼哈顿距离是指在几何空间中两点之间的距离&#xff0c;其计算方法是通过将两点在各个坐标轴上的差值的绝对值相加得到。在二维空间中&#xff0c;曼哈顿距离可以表示为两点在横纵坐标上的差值的绝对值之和&#xff1b;在三维空间中&#xff0…

第十五届蓝桥杯第三期模拟赛第十题 ← 上楼梯

【问题描述】 小蓝要上一个楼梯&#xff0c;楼梯共有 n 级台阶&#xff08;即小蓝总共要走 n 级&#xff09;。小蓝每一步可以走 a 级、b 级或 c 级台阶。 请问小蓝总共有多少种方案能正好走到楼梯顶端&#xff1f;【输入格式】 输入的第一行包含一个整数 n 。 第二行包含三个整…

鸿蒙OS开发实战:【Socket小试MQTT连接】

本篇分享一下 HarmonyOS 中的Socket使用方法 将从2个方面实践&#xff1a; HarmonyOS 手机应用连接PC端 SocketServerHarmonyOS 手机应用连接MQTT 服务端 通过循序渐进的方式&#xff0c;全面了解实践HarmonyOS中的Socket用法 学习本章前先熟悉文档开发知识更新库gitee.com…

马蹄集第九周

MT3011 代码 #include<bits/stdc.h> using namespace std; const int N 1e3 7;int n; struct NODE{vector<int> v;int ind 0; }g[N];int main( ) {cin >> n;int x;for(int i 1; i < n; i){for(int j 1; j< n-1; j){cin >> x;g[i].v.push_…

笔迹/签名数据集汇总

这里只收集公开/易申请的数据集 数据集发表年份语言最小单元Writers/人规模颜色最小单元文件格式示例图片备注CSAFE Handwriting Database2019英语页9090 人*(3 次*9 个样本) 2430 页300 dpi 扫描png-HWDB2.0-2.22011汉字页1,019每人 5 页,共 5091 页灰度图dgrl-CEDAR2006英语…