内存管理————基础理解

news2025/1/12 23:02:34

 

目录

我们先看以下代码和内存分布图

对一些名词的解释说明:

题目

答案

问题解释:

C语言中动态内存管理方式

C语言中动态内存管理方式:malloc/calloc/realloc/free

这里提一下要注意的点

C++内存管理方式

基本内容

new/delete操作内置类型:

new和delete操作自定义类型:

operator new与operator delete函数

基本简绍

仔细分析:

operator new

operator delete

总结

new和delete的实现原原理

申请的是内置类型的空间

 申请的是自定义类型

new的原理

delete的原理

new T[N]的原理

delete[]的原理

扩展内容

定位new表达式(placement-new) (了解)

使用场景:

malloc/free和new/delete的区别


在学习完之前c++的一些基础内容后,我们也应该了解一些c++的内存管理是怎么样的;先浅层的了解这些内容,如此能帮助我们刚好的理解并接受往后的内容。

我们先看以下代码和内存分布图

对一些名词的解释说明:

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

题目

看完以上部分就做下面的题来巩固一下吧;

答案

C C C A  A

A A A D A B

在这里存在最大的争议的可能是  *char2 和 *pchar3 

问题解释:

若有其他的问题可以留言评论哦;

C语言中动态内存管理方式


C语言中动态内存管理方式:malloc/calloc/realloc/free

这里递上malloc,calloc,realloc,free的具体使用的链接;不会的要记得回忆一下哦

不太清楚的要复习一下哦。


这里提一下要注意的点

malloc:开辟成功返回指针,不成功返回NULL 要主要检查,(这里就体现了new的好处)

free:的参数可以是null,这样就是什么都不做;还有就是如果参数不是动态开辟的,那么这个free函数就是未定义的;

calloc:与malloc差就差在 calloc 可以将开辟的位置初始化

realloc:在原有的空间上扩大;会有两种一种原地扩大,一种换一个堆上的地址扩大,数据也会原封不动的移动过去;

C++内存管理方式

基本内容

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因

此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

new/delete操作内置类型:


基本用法:

void Test1()
{
	// 动态申请一个int类型的空间
	int* ptr4 = new int;

	// 动态申请一个int类型的空间并初始化为10
	int* ptr5 = new int(10);
	
	// 动态申请10个int类型的空间
	int* ptr6 = new int[3];

	int n = 8;
	//一些编译器如 VS 不支持这种写法,就可以用new来代替
	//int arr[n] = { 0 };
	
	int* arr = new int[n];
	
	delete ptr4;
	delete ptr5;
	delete[] ptr6;
}

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

new和delete操作自定义类型:

基本用法:

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

int main()
{
	//new/delete 和 malloc/free最大区别是
	//new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数
	A* p1 = (A*)malloc(sizeof(A));
	A* p2 = new A(1);
	free(p1);
	delete p2;

	// 内置类型是几乎是一样的
	int* p3 = (int*)malloc(sizeof(int)); // C
	int* p4 = new int;
	free(p3);
	delete p4;

	return 0;
}

注意:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。这就是他们的最大区别,也是new的优势。

operator new与operator delete函数

基本简绍

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

仔细分析:

operator new


operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试执行空间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛出bad_alloc 类型异常。

operator delete

operator delete: 该函数最终是通过free来释放空间的

free的实现

#define   free(p)       _free_dbg(p, _NORMAL_BLOCK)

因此free  是通过 _free_dbg实现的

总结

通过上述两个全局函数的实现知道,operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。


 

new和delete的实现原原理

申请的是内置类型的空间

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

因此内置类型不在堆上创建空间(不用调用构造函数,malloc);他们与自定义类型不一样就不一样在内置类型不申请空间在堆上。简单来说内置类型在类中不用写构造函数都能运行,但是自定义类型不可以;

(也可以怎么理解,在类和对象的内容讲过,如果不用自主构造函数,那么析构函数,拷贝构造都不用自主实现,用编译器即可。这里就是不用自主构造函数,使用new就不会使用malloc)

 申请的是自定义类型


new的原理

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

根据反汇编可以看出来,两次call  分别调用

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来释放空间

扩展内容

定位new表达式(placement-new) (了解)

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

使用格式:new (place_address) type或者new (place_address) type(initializer-list) place_address必须是一个指针,initializer-list是类型的初始化列表。

使用场景:

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

举一个简单的例子

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

// 定位new
int main()
{
//p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行
A* p1 = (A*)malloc(sizeof(A));
new(p1)A;                     //如果A类的构造函数有参数时,此处需要传参
p1->~A();
//这里内置类型free的原因是,提前在堆上
//申请了空间;再说释放的也不是内置类型而是,存他们的空间
free(p1);

//原理同上
A* p2 = (A*)operator new(sizeof(A));
new(p2)A(10);
p2->~A();
operator delete(p2);
}

 

malloc/free和new/delete的区别
 

  1. malloc申请的空间不会初始化,new可以初始化
  2. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理释放
  3. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常
  4. malloc和free是函数,new和delete是操作符
  5. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
  6. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可。(主要原因还是,会调用析构)
     

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

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

相关文章

常用API:object

文章目录 Object类toString()方法equals()方法总结其他方法 黑马学习笔记 Object类 是所有类的父类&#xff0c;所有的类都默认继承Object类。Java中所有的类的对象都可以直接使用Object类提供的一些方法。 toString()方法 equals()方法 默认是判断两个对象的地址 也是判断…

MATLAB-疲劳检测

首先&#xff0c;我们需要解决一个问题&#xff0c;什么样可以视为疲劳&#xff1f; 频繁的眨眼/眨一次眼所用时间很长 不停的打哈欠 不停的点头 通过分析&#xff0c;我们得到了检测疲劳的三个标准&#xff1a;眨眼&#xff0c;打哈欠&#xff0c;头部姿态。 这三个标准可以…

OpenCV findTours函数及其用法

OpenCV findTours函数主要用以寻找图像中物体的轮廓&#xff0c;其原型如下&#xff1a; indTours 函数参数&#xff1a; Image 输入图像&#xff0c;需8位单通道图像。非零像素被视为1。零像素保持为0&#xff0c;因 此图 像被视为 二进制。您可以使用co…

【数据分享】《全国能源-分行业煤油消费总量》(2000-2020年)

而今天要限时免费分享的数据就是2000-2020年间出版的《全国能源-分行业煤油消费总量》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 在过去的二十年里&#xff0c;中国作为全球能源消费的重要力量&#xff0c;其能源结构的变化不仅影…

基于x86 平台opencv的图像采集和seetaface6的图像质量评估功能

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 配置资源文件3.2 验证功能一、概述 本文档是针对x86 平台opencv的图像采集和seetaface6的图像质量评估功能,opencv通过摄像头采集视频图像,将采集的视频图像送给seetaface6的图像质量评估模块…

21.1 基于Netty实现聊天

21.1 基于Netty实现聊天 一. 章节概述二. `Netty`介绍三. 阻塞与非阻塞1. 阻塞与非阻塞简介2. BIO同步阻塞3. NIO同步非阻塞4. AIO异步非阻塞IO5. 异步阻塞IO(用的极少)6. 总结四. Netty三种线程模型1. 单线程模型2. 多线程模型3. 主从线程模型五. 构建Netty服务器************…

DDL——三范式与表约束

目录 一、三大范式 1.范式的定义 2.第一范式 3.第二范式 4.第三范式 二、表约束 1.约束的定义 2.非空约束&#xff08;not null&#xff09; 3.唯一性约束&#xff08;unique&#xff09; 4.主键约束&#xff08;primary key&#xff09; 5.外键约束&#xff08;fo…

可集成多模型的机器人开发框架 dora:让机器人编程走向大众

作者 | Annie Xu 责编 | 何苗 出品 | GOSIM 开源创新汇 C 和 C是机器人编程中常用的编程语言&#xff0c;但学起来存在一定难度。那些对机器人感兴趣&#xff0c;但没有精力花费数周时间学习 C 和 C编程的用户只能望而却步。 为了让机器人技术变得更简单&#xff0c;陶海轩&a…

AWS SAM CLI 备忘单!

安装 AWS SAM CLI brew tap aws/tap brew 安装 aws-sam-cli 验证安装 $ sam --version 升级 SAM $ brew upgrade aws-sam-cli 您需要 AWS 凭证才能在 AWS 上工作。 构建并部署简单应用程序 $ sam init→ 下载示例应用程序 $ sam build→ 构建您的应用程序 $ sam deploy --guid…

机器学习:决策树回归树实现

1、决策树&#xff1a; 是一种树形结构&#xff0c;用于通过一系列的是非问题来预测目标值。在决策树回归中&#xff0c;树的叶子节点代表预测的连续值。 2、数据准备&#xff1a; 收集数据集&#xff0c;并对其进行清洗和预处理。 将数据集分为特征&#xff08;X&#xff09;…

git-20240822

目录 初始化仓库 Git init Git init project --bare 查看提交的记录 git log --prettyoneline 查看当前git远程库地址 git remote -v 查看详细提交记录 git log 撤出暂存区的文件 git reset HEAD file(.代表全部文件&#xff09; 提交数据到远程仓库 git config --global push.…

4.6算法之贪心_702:Crossing River

题目 702:Crossing River 总时间限制: 1000ms 内存限制: 65536kB 描述 A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat…

【TB作品】普中V2,数字时钟万年历显示,音乐闹钟,流水灯,Proteus仿真

文章目录 功能硬件原理图LCD1602独立按键LED灯ds1302蜂鸣器 引脚汇总按键功能code 功能 带闹钟和花样流水灯的LCD数显实时时钟设计&#xff08;运用DS1302时钟模块&#xff0c;LCD显示&#xff0c;带万年历&#xff0c;时间到响音乐显示花样流水灯&#xff09; 万年历显示 按…

禹神:三小时快速上手TypeScript,TS速通教程(上篇、中篇、下篇,3合1笔记),根据视频整理

TypeScript快速上手 &#x1f4da;一、TypeScript简介 1.TypeScript由微软开发&#xff0c;是其于JavaScript的一个扩展语言. 2.TypeScript包含了JavaScript的所有内容&#xff0c;即&#xff1a;TypeScript是JavaScript的超集 3.TypeScript增加了&#xff1a;静态奖型检查、接…

Win10安装ChatTTS-2024-cuda10.1

0x00 前言 ChatTTS是专门为对话场景设计的文本转语音模型&#xff0c;例如大语言助手对话任务。它支持英文和中文两种语言。最大的模型使用了10万小时以上的中英文数据进行训练。目前在huggingface中的开源版本为4万小时训练且未SFT的版本。 0x01 准备环境 版本操作系统Win1…

大模型参数高效微调技术总结

基础知识 最近&#xff0c;OpenAI推出的ChatGPT展现出了卓越的性能&#xff0c;引发了大规模语言模型(Large Language Model, LLM)的研究热潮。大规模语言模型的“大”体现在两个方面&#xff1a;模型参数规模大&#xff0c;训练数据规模大。以GPT3为例&#xff0c;GPT3的参数…

springboot集成redis之接口缓存

什么是redis的接口缓存&#xff1f; Redis的接口缓存是一种利用Redis这种内存数据库来存储接口&#xff08;API&#xff09;响应数据的技术&#xff0c;以提高应用程序的响应速度和性能。具体来说&#xff0c;当用户请求一个接口时&#xff0c;系统会首先检查Redis缓存中是否已…

windows vs2022 MFC使用webview2嵌入网页

Microsoft Edge WebView2 控件允许在本机应用中嵌入 web 技术(HTML、CSS 以及 JavaScript)。 WebView2 控件使用 Microsoft Edge 作为绘制引擎&#xff0c;以在本机应用中显示 web 内容。 一、通过菜单“项目”-“管理NuGet程序包”&#xff0c;下载相关包 二、安装 Microsof…

windows ssh launch Jenkins

一、 windows server2012 ssh launch jenkins 经过一系列测试验证发现&#xff0c;windows server2012始终无法launch到jenkins master。配置ssh之后 [08/21/24 10:08:03] [SSH] Opening SSH connection to 172.xx.xx.xx:18822. [08/21/24 10:08:03] [SSH] WARNING: SSH Host …

DBeaver连接GBase 8s数据库的步骤

最近在学习国产数据库GBase 8s。酷酷一顿操作后&#xff0c;发现自带的 dbaccess 不好用&#xff0c;然后尝试用DBeaver这种图形界面来尝试使用。 本次使用工具&#xff1a; 1、dbeaver-ce-24.1.4 2、GBase 8s Server 8.8 一、搭建环境&#xff0c;官方建议使用的是CentOS 7.3&…