C++(9)——内存管理

   

1. 内存分类:

    在前面的文章中,通常会涉及到几个名词,例如:栈、堆。这两个词所代表的便是计算机内存的一部分 。在计算机中,对系统的内存按照不同的使用需求进行了区分,大致可以分为:栈 、堆、数据段、代码段。其各个具体解释如下:
      1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
      2. 堆用于程序运行时动态内存分配,堆是可以上增长的。
      3. 数据段(静态区)--存储全局数据和静态数据。
      4. 代码段(常量区)--可执行的代码/只读常量。

为了更加深入的了解各个内存空间之间的差异,下面给出一个例子:

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. 对于变量globalVar,是一个全局变量,存储在数据段(静态区)。

2.对于变量staticGlobalVar,在定义的时候加上了关键字static,存放在数据段(静态区)。

前两个变量虽然都存储在数据段(静态区),但是二者的链接属性并不相同,对于globalVar,可以在同一工程下的不同文件中共享使用。但是对于staticGlobalVar,只能在本文件中使用。

3. 对于变量staticVar,也是一个被关键字static修饰的静态变量,同样存储在数据段(静态区),但是只能在本函数内部使用。

4.对于变量localVar,是函数内部的一个临时变量,存储在栈区

5.对于变量num1,是一个函数内部的数组,存储在栈区

6.对于变量char2,与变量num1同理,都是存储在

	int* n1 = new int;

栈区上的

7.对于变量*char2,与num1类似,存储在栈区上

8.对于变量pchar3,需要注意,在定义这个变量时,前面的const修饰的并不是pchar3,而是*pchar3。因此,pchar3也是存储在栈区,但是需要注意,*pchar3,即字符串abcd则是存储在代码段(常量区)。

9.对于ptr1,与pchar3类似,也是存储在栈区上的,但是*ptr1,即后面利用malloc开辟的空间是在堆区的。因此*ptr1是存储在堆区上的

2. C++中的内存管理:

2.1 开辟内存空间:

       在C语言中,对于内存的管理通常是使用malloc,realloc,free等函数完成的,在数据结构中,经常在创建一个关于数据结构的单个结点时使用。在C++中,引入了两个关键字new,delete来实现内存管理。其中,new用来开辟内存空间,delete用来释放开辟的内存空间。对于这两个操作符的使用,下面将引入若干例子来说明:
       

       1. 开辟一个类型为int的空间:

int* n1 = new int;

      2.一次性开辟10个类型为int的空间:

int* n1 = new int[10];

     在C语言——动态内存管理:_编写内存管理代码-CSDN博客中提到,对于函数malloc,只能开辟空间,并不能对开辟的空间进行初始化。而函数calloc可以在开辟空间的同时将所开辟的空间初始化为0。对于关键字new,在上面的使用方法中,同样无法完成对于开辟空间的初始化。如果想初始化开辟的空间,例如将开辟的一个类型为int的空间初始化为0,则:
 

int* n2 = new int(0);  //开辟一个类型为Int的空间,初始化为0

运行结果如下:

若需要同时初始化多个空间,则:

int* n3 = new int[10]{ 1,2,3 }; //开辟10个类型为int的空间,并初始化其中三个空间为1,2,3

 运行结果如下:

       不难发现,在上述代码中,开辟了10个空间,但是仅对其中三个进行了初始化。对于其他的空间,默认初始化为0

2.2 释放内存空间:

   针对使用关键字new开辟的内存空间,需要用关键字delete进行删除。对于单个空间的释放,代码如下:

int* n = new int;      //开辟一个空间,类型为intdelete n; //释放上方开辟的空间

对于多个空间的释放,代码如下:
 

int* n1 = new int[10]; //开辟10个类型为int的空间delete[]n1;   //释放上面开辟的10个空间

3. 为什么要引入这两个关键字:

    前面说到,new,delete这两个关键字是在C++中引入的,虽然C语言中的函数malloc,calloc,realloc,free已经满足了对于内存的开辟及释放。但是,这些函数针对于自定义类型并不能解决初始化的问题。因此,需要引入newdelete来完成开辟自定义类型空间时的初始化问题。例如对于下方给出的自定义类型:

class A
{
public:A(int a = 0):_a(a){cout << " A() " << " " << this << endl;}~A(){cout << " ~A() " << " " << this << endl;}
private:int _a;
};

按照上方new开辟空间的方式,来开辟一个类型为A的空间,代码为:

A* n4 = new A;  //开辟一个类型为A的空间

       而针对于new如何对开辟的空间进行初始化。可以认为,在调用关键字new开辟空间时,关键字进行了两步:第一步是开辟空间,第二步则是调用自定义类型的默认构造函数(全缺省、不需要传参就可以调用、编译器自动生成),对于上述代码中的类,由于其构造函数中的参数为全缺省,因此可以看作一个默认构造函数,但运行上方代码时,结果如下:

   通过结果可以得知,在开辟空间时调用了自定义类型A的默认构造函数。 

如果想要显式调用,即不适用类中的构造函数的参数,方法如下:

A* n5 = new A(1);

类中成员变量如下:

上述开辟自定义类型空间只是开辟了一个,对于开辟多个自定义类型的空间,代码如下:

A* n6 = new A[5];

运行结果如下:

 对于开辟多个空间的初始化,有下面几种方法:

A a1(1);A a2(2);A a3(3);A* n7 = new A[3]{ a1,a2,a3 };

 同时,可以借助匿名对象来达成初始化的效果:

A* n8 = new A[3]{A(1), A(2), A(3)};

此外,如果自定义类型的构造函数满足单参数这一条件

(注:单参数并不准确,具体条件可以在C++类与对象基础(8)-CSDN博客进行查看)

可以借助隐式类型转换来完成初始化,即:

A* n9 = new A[3]{ 4,5,6 };

对于自定义类型空间的释放,代码如下:

	cout << "测试自定义类型空间的释放" << endl;A* n9 = new A[3]{ 4,5,6 };delete[]n9;

运行结果如下:

不难发现,代码在运行中调用了析构函数。原因是对于关键字delete,其动作过程也可以分为两步: 调用自定义类型的析构函数、释放空间。

4. 勘误:

  由于个人能力有限,书中难免出现汉字拼写错误、代码意义解释错误、内容逻辑以及理解错误等不同类型的错误。首先感谢各位大佬能花掉自己宝贵的时间阅读此文章,愿大佬们斧正,发现错误可以通过私信联系,本人不胜感激。

 

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

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

相关文章

41k+ stars 闪电般快速的开源搜索引擎 docker安装教程

目录 1.下载 2.启动 成功示例 3.创建索引 4.插入数据 4.1下载数据 4.2插入数据 4.3查看数据 5.官方地址 1.下载 docker pull getmeili/meilisearch:latest 2.启动 mkdir -p /opt/meili_datadocker run -it --rm \-p 7700:7700 \-v /opt/meili_data:/meili_data \ge…

YOLOV7剪枝流程

YOLOV7剪枝流程 1、训练 1&#xff09;划分数据集进行训练前的准备&#xff0c;按正常的划分流程即可 2&#xff09;修改train.py文件 第一次处在参数列表里添加剪枝的参数&#xff0c;正常训练时设置为False&#xff0c;剪枝后微调时设置为True parser.add_argument(--pr…

Linux第28步_编译“正点原子的TF-A源码”

编译“正点原子的TF-A源码”&#xff0c;目的是想得到TF-A文件&#xff0c;即“tf-a-stm32mp157d-atk-trusted.stm32”。 在前27步的基础上&#xff0c;才可以学习本节内容&#xff0c;学习步骤如下&#xff1a; 1、创建“alientek_tf-a”目录&#xff1b; 2、复制正点原子的…

.【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)

概率图模型是一种用图形表示概率分布和条件依赖关系的数学模型。概率图模型可以分为两大类&#xff1a;有向图模型和无向图模型。有向图模型也叫贝叶斯网络&#xff0c;它用有向无环图表示变量之间的因果关系。无向图模型也叫马尔可夫网络&#xff0c;它用无向图表示变量之间的…

02.部署LVS-DR群集

技能展示&#xff1a; 了解LVS-DR群集的工作原理 会构建LVS-DR负载均衡群集 2.1 LVS-DR 集群 LVS-DR&#xff08; Linux Virtual Server Director Server &#xff09;工作模式&#xff0c;是生产环境中最常用的一种工作模式。 2.1.1&#xff0e;LVS-DR 工作原理 LVS-DR 模式&…

Spark---RDD持久化

文章目录 1.RDD持久化1.1 RDD Cache 缓存1.2 RDD CheckPoint 检查点1.3 缓存和检查点区别 1.RDD持久化 在Spark中&#xff0c;持久化是将RDD存储在内存中&#xff0c;以便在多次计算之间重复使用。这可以显著减少不必要的计算&#xff0c;提高Spark应用程序的性能。 val line…

蓝桥杯练习题(七)

&#x1f4d1;前言 本文主要是【算法】——蓝桥杯练习题&#xff08;七&#xff09;的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 …

kotlin运行

1.使用android studio 由于我本身是做android的&#xff0c;android studio本身有内置kotlin的插件。但若只是想跑kotlin的程序&#xff0c;并不像和android程序绑在一起&#xff0c;可以创建一个kt文件&#xff0c;在里面写一个main函数&#xff0c;就可以直接运行kotlin程序…

【机器学习 西瓜书】期末复习笔记整理

一些杂点&#xff1a; 测试集如何归一化&#xff1f; —— 不是用测试集的均值和标准差&#xff0c;而是用训练集的&#xff01; 机器学习&#xff1a; 对计算机一部分数据进行学习&#xff0c;然后对另外一些数据进行预测与判断。 参考计算例题&#xff1a; 机器学习【期末复习…

PyCharm安装使用教程2024

简介 PyCharm是一种PythonIDE&#xff08;Integrated Development Environment&#xff0c;集成开发环境&#xff09;&#xff0c;带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单…

[oeasy]python0004_游乐场_和python一起玩耍_python解释器_数学运算

和python玩耍 &#x1f94a; Python 回忆 上次 了解shell环境中的命令 命令作用whoami显示当前用户名pwd显示当前文件夹ls列出当前文件夹下的内容python3仿佛进入大于号黑洞 这python3 怎么玩啊&#xff01;&#x1f620; 说好的python教程呢&#xff1f;&#x1f914; 运…

vue2使用Lottie

文章目录 学习链接1.安装依赖2.创建lottie组件3.在相对应的页面应用4.相关data.json5.测试效果 学习链接 原文链接&#xff1a;lottie在vue中的使用 lottie官网&#xff1a;https://lottiefiles.com/ 1.安装依赖 npm install lottie-web2.创建lottie组件 <template>…

MetaGPT前期准备与快速上手

大家好&#xff0c;MetaGPT 是基于大型语言模型&#xff08;LLMs&#xff09;的多智能体协作框架&#xff0c;GitHub star数量已经达到31.3k。 接下来我们聊一下快速上手 这里写目录标题 一、环境搭建1.python 环境2. MetaGpt 下载 二、MetaGPT配置1.调用 ChatGPT API 服务2.简…

Maven的安装和配置

国内Maven仓库之阿里云Aliyun仓库地址及设置 用过Maven的都知道Maven的方便便捷&#xff0c;但由于某些网络原因&#xff0c;访问国外的Maven仓库不便捷&#xff0c;好在阿里云搭建了国内的maven仓库。 需要使用的话&#xff0c;要在maven的settings.xml 文件里配置mirrors的子…

HTTP 常见协议:选择正确的协议,提升用户体验(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

SQL语句详解二-DDL(数据定义语言)

文章目录 操作数据库创建&#xff1a;Create查询&#xff1a;Retrieve修改&#xff1a;Update删除&#xff1a;Delete使用数据库 操作表常见的几种数据类型创建&#xff1a;Create复制表 查询&#xff1a;Retrieve修改&#xff1a;Update删除&#xff1a;Delete 操作数据库 创…

Stable Diffusion XL Turbo 文生图和图生图实践

本篇文章聊聊&#xff0c;如何快速上手 Stable Diffusion XL Turbo 模型的文生图和图生图实战。 写在前面 分享一篇去年 11 月测试过模型&#xff0c;为月末分享的文章做一些技术铺垫&#xff0c;以及使用新的环境进行完整复现。 本篇文章相关的代码保存在 soulteary/docker…

【教学类-43-18】A4最终版 20240111 数独11.0 十宫格X*Y=Z套(n=10),套用没有分割行列的A4横版模板

作品展示&#xff1a; 撑满格子的10宫格数独50%难度 50空 背景需求&#xff1a; 大4班有3位男孩做9宫格数独&#xff08;81格子&#xff0c;30%难度 24空&#xff09;非常娴熟&#xff0c;我观察他们基本都在10分钟内完成&#xff0c;其中一位男孩把九宫格题目给我看时表达自…

使用 EmbeddingBag 和 Embedding 完成词嵌入

&#x1f368; 本文为[&#x1f517;365天深度学习训练营学习记录博客\n&#x1f366; 参考文章&#xff1a;365天深度学习训练营\n&#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制]\n&#x1f680; 文章来源&#xff1a;[K同学的学习圈子](https://www.yuque.co…

移除两个双向链表中的重复元素,每个链表中的元素不重复

移除两个双向链表中的重复元素&#xff0c;每个链表中的元素不重复&#xff0c;请给出算法。 ans: 该问题比单向链表要更加复杂一些&#xff0c;必须考虑并更新前向节点的指向情况&#xff0c;具体编码中存在一些难度&#xff0c;加上链表调试相对不容易&#xff0c;因此难度系…