Lesson 03 C/C++内存管理

C++:渴望力量吗,少年?

文章目录

  • 一、C++内存管理方式
    • 1. new/delete操作内置类型
    • 2. new和delete操作自定义类型
  • 二、operator new与operator delete函数
  • 三、new和delete的实现原理
    • 1. 内置类型
    • 2. 自定义类型
  • 四、内存泄漏
    • 1. 什么是内存泄漏
    • 2. 内存泄漏的危害
    • 3. 堆内存泄漏(Heap leak)
    • 4. 解决方案


一、C++内存管理方式

  C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

1. new/delete操作内置类型

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

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

	// 动态申请10个int类型的空间
	int* ptr6 = new int[3];

	delete ptr4;
	delete ptr5; 
	delete[] ptr6;

	// 额外支持开空间+初始化
	int* p6 = new int(10);//注意这里是赋值为10
	int* p7 = new int[10]{1,2,3};//和C语言一样,这种情况下没有初始化到的部分默认为0
	int* p8 = new int[10]{};

	return 0;
}

在这里插入图片描述

2. new和delete操作自定义类型

  在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。而他们对内置类型是几乎是一样的。

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

	~A()
	{
		cout << "~A():" << this << endl;
	}

private:
	int _a;
};
int main()
{
	// malloc没有办法很好支持动态申请的自定义对象初始化
	A* p1 = (A*)malloc(sizeof(A));
	//p1->_a = 0;
	//p1->A(1);

	// 自定义类型,开空间的同时调用构造函数初始化
	A* p2 = new A;
	A* p3 = new A(3);

	// 自定义类型,调用析构函数+释放空间
	delete p2;
	delete p3;

	A* p4 = new A[10];
	delete[] p4;

/*下面三种写法都是一样的
	A aa1(1);
	A aa2(2);
	A* p5 = new A[10]{ aa1, aa2 };
	delete[] p5;

	A* p6 = new A[10]{ A(1), A(2) };
	delete[] p6;

	A* p7 = new A[10]{ 1, 2 };
	delete[] p7;
*/
	return 0;
}

二、operator new与operator delete函数

  new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
  operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试执行空间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常

typedef char DataType;
class Stack
{
public:
	Stack(size_t capacity = 4)
	{
		cout << "Stack()" << endl;

		_array = new DataType[capacity];//析构函数对应也得用delete释放空间
		//_array = new char[0x7ffffffffff];//如果取消注释,那么对应的第二段代码会抛出异常

		_capacity = capacity;
		_size = 0;
	}

	void Push(DataType data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}

	~Stack()
	{
		cout << "~Stack()" << endl;

		delete[] _array;
		_array = nullptr;
		_size = _capacity = 0;
	}
private:
	// 内置类型
	DataType* _array;
	int _capacity;
	int _size;
};
class A
{
public:
	A(int a = 0)
		:_a1(a)
	{}

	~A()
	{
		cout << "~A()" << endl;
	}

private:
	int _a1;
};
int main()
{
	Stack* pst1 = (Stack*)operator new(sizeof(Stack));//相当于malloc,创造它是为了符合抛出异常的方式
	operator delete(pst1);//相当于free
	//其实上面两个函数主要都不是让我们直接使用,而是分别封装在new和delete中,new就相当于operator new和调用构造函数

	Stack* pst2 = new Stack;
	delete pst2;
	//free(pst2);

	A* p2 = new A[10];
	delete[] p2;
	return 0;
}

  new和delete一定要匹配使用,否则后果可能是未定义的!!!

三、new和delete的实现原理

1. 内置类型

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

2. 自定义类型

(1)new的原理
    a.调用operator new函数申请空间
    b.在申请的空间上执行构造函数,完成对象的构造
(2)delete的原理
    a.在空间上执行析构函数,完成对象中资源的清理工作
    b.调用operator delete函数释放对象的空间
(3)new T[N]的原理
    a.调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
    b.在申请的空间上执行N次构造函数
(4)delete[]的原理
    a.在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
    b.调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

四、内存泄漏

1. 什么是内存泄漏

  内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

2. 内存泄漏的危害

  长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。

void MemoryLeaks()
{
	// 1.内存申请了忘记释放
	int* p1 = (int*)malloc(sizeof(int)); 
	int* p2 = new int;

	// 2.异常安全问题
	int* p3 = new int[10];
	Func(); 
	// 这里Func函数抛异常导致 delete[] p3未执行,p3没被释放. 
	delete[] p3;
}

3. 堆内存泄漏(Heap leak)

  作为初学者,我们更加关注的是这方面的泄露。堆内存指的是程序执行中依据须要分配通过malloc / calloc / realloc / new等从堆中分配的一块内存,用完后必须通过调用相应的 free或者delete 删掉。假设程序的设计错误导致这部分内存没有被释放,那么以后这部分空间将无法再被使用,就会产生Heap Leak。

4. 解决方案

内存泄漏非常常见,一般解决方案分为两种:
(1)事前预防型。如智能指针等;
(2)事后查错型。如泄漏检测工具。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Python实现大型家用电器和电子产品在线商店购买数据分析【500010098】

导入模块 import pandas as pd import numpy as np import matplotlib.pyplot as plt获取数据 df pd.read_csv( r"./data/kz.csv",sep,)数据描述 该数据包含2020年4月至2020年11月从大型家用电器和电子产品在线商店购买的数据。 数据说明 event_time&#xff1a…

[最新榜单] 智能手机数据恢复的 10 款最佳应用

当手机上的数据消失时&#xff0c;这让您感到非常难过。 由于事故而突然丢失重要的聊天记忆、照片和其他您想保留的东西的悲伤。 如果它没有被淹没&#xff0c;您可以使用数据恢复应用程序修复它。 在本文中&#xff0c;我们将解释一些有用的数据恢复应用程序。 数据恢复应用…

「Verilog学习笔记」数据选择器实现逻辑电路

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 将变量A、B接入4选1数据选择器选择输入端S0 S1。将变量C分配在数据输入端。从表中可以看出输出L与变量C的关系。 当AB00时选通D0而此时L0&#xff0c;所以数据端D0接0…

PyTorch 实战之水果分类

当我们试图提高神经网络的准确性时&#xff0c;经常会遇到过拟合训练数据的情况。当我们运行测试数据的模型时&#xff0c;这会导致一个糟糕的预测。因此&#xff0c;我采取了一个数据集&#xff0c;并应用这些技术&#xff0c;不仅提高准确性&#xff0c;而且还处理过拟合的问…

AI技术:分享8个非常实用的AI绘画网站

目录 1、Midjourney 2、Stable Diffusion Omline 3、Microsoft Designer 4、Craiyon 5、NightCafe Studio 6、Wombo 7、Dalle-2 8、Avatar AI 1、Midjourney 特点&#xff1a;业内标杆&#xff0c;效果最强大 Midjourney是基于diffusion的AI图画艺术生成器。生成图片不…

OpenAI GPT-4 Turbo发布:开创AI新时代

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; IT杂谈 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. GPT-4 Turbo的突破1.1上下文长度和控制手段的加强&#xff1a;1.2多模态支持&#xff1a…

vb.net U盘或移动硬盘 插入 自动(静默)复制指定格式文件

U盘或移动硬盘 插入 自动复制指定格式文件至系统盘符 开发语言&#xff1a;vb.net 重要申明&#xff1a;该程序只是防止本人不在电脑旁时&#xff0c;别人偷偷copy你的电脑文件&#xff0c;让他偷鸡成了也要蚀把米。严禁从事黑客或违反道德等不良行为&#xff0c;故而不发布程…

通信原理板块——奇偶监督码、方阵码、恒比码、正反码

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 1、奇偶监督码(parity check) 奇偶…

微信小程序开发---实现文件上传和下载

在开发小程序的过程中&#xff0c;我们难免会遇到使用小程序对后端发送文件&#xff1b;或者接收后端的文件&#xff0c;本文章将手把手带你简单高效实现微信小程序的文件上传下载功能 前期准备 由于目前小程序保护用户个人隐私力度加大 &#xff0c;因此我们要想实现文件上传…

uniapp优化h5项目-摇树优化,gzip压缩和删除console.log

1.摇树优化 勾选摇树优化,打包删除死代码 2.gzip压缩和删除console.log 安装插件webpack和compression-webpack-plugin webpack插件 npm install webpack4.46.0 --save-devcompression-webpack-plugin插件 npm install compression-webpack-plugin6.1.1 --save-devconst Com…

为什么C++标准库中atomic shared_ptr不是lockfree实现?

为什么C标准库中atomic shared_ptr不是lockfree实现&#xff1f; 把 shared_ptr 做成 lock_free&#xff0c;应该是没有技术上的可行性。shared_ptr 比一个指针要大不少&#xff1a;最近很多小伙伴找我&#xff0c;说想要一些C的资料&#xff0c;然后我根据自己从业十年经验&am…

CVE-2021-42287CVE-2021-42278 域内提权

倘见玉皇先跪奏&#xff1a;他生永不落红尘 本文首发于先知社区&#xff0c;原创作者即是本人 前言 网络安全技术学习&#xff0c;承认⾃⼰的弱点不是丑事。只有对原理了然于⼼&#xff0c;才能突破更多的限制。拥有快速学习能力的白帽子&#xff0c;是不能有短板的&#xf…

四、hdfs文件系统基础操作-保姆级教程

1、启动Hadoop集群 想要使用hdfs文件系统&#xff0c;就先要启动Hadoop集群。 启动集群: start-dfs.sh 关闭集群: stop-dfs.sh 2、文件系统构成 &#xff08;1&#xff09;基础介绍 其实hdfs作为分布式存储的文件系统&#xff0c;其构成和Linux文件系统构成差不多一…

monaco-editor 简单使用

一. 文件调用示例 1. 安装package包 官方文档 "monaco-editor": "^0.28.1", "monaco-editor-webpack-plugin": "^4.2.0", Copy 请注意安装包的版本号 monaco-editor-webpack-pluginmonaco-editor7.*.*> 0.31.06.*.*0.30.*5.*.*…

STM32/N32G455国民科技芯片驱动DS1302时钟---笔记

这次来分享一下DS1302时钟IC&#xff0c;之前听说过这个IC&#xff0c;但是一直没搞过&#xff0c;用了半天时间就明白了原理和驱动&#xff0c;说明还是很简单的。 注&#xff1a;首先来区分一下DS1302和RTC时钟有什么不同&#xff0c;为什么不直接用RTC呢&#xff1f; RTC不…

基于社会群体算法优化概率神经网络PNN的分类预测 - 附代码

基于社会群体算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于社会群体算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于社会群体优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

秋招算法高频算法笔试题

自己在秋招过程中遇到的算法笔试题&#xff0c;包含中大厂&#xff0c;都附解析&#xff01; 汽水瓶 如果汽水瓶数目为1或者0&#xff0c;那么一瓶都喝不到 如果汽水瓶数目为2或者3&#xff0c;那么只能喝到一瓶 如果为2&#xff0c;喝到一瓶后手里一个瓶子都没有了&#xff…

【数据结构】树与二叉树(十九):树的存储结构——左儿子右兄弟链接结构(树、森林与二叉树的转化)

文章目录 5.1 树的基本概念5.1.1 树的定义5.1.2 森林的定义5.1.3 树的术语 5.2 二叉树5.3 树5.3.1 树的存储结构1. 理论基础2. 典型实例3. Father链接结构4. 儿子链表链接结构5. 左儿子右兄弟链接结构a. 定义树节点b. 创建树节点c. 使用左儿子右兄弟链接结构将树转化为二叉树d.…

NET8 BlazorAuto渲染模式

.NET8发布后&#xff0c;Blazor支持四种渲染方式 静态渲染&#xff0c;这种页面只可显示&#xff0c;不提供交互&#xff0c;可用于网页内容展示使用Blazor Server托管的通过Server交互方式使用WebAssembly托管的在浏览器端交互方式使用Auto自动交互方式&#xff0c;最初使用 …

嵌入式系统中相关的高质量开源项目

关于GitHub&#xff0c;可能很多人误以为这是互联网人的专属&#xff0c;其实并不是&#xff0c;那上面嵌入式相关的开源项目是有很多的。现分享一些高星开源项目&#xff08;像RT-Thread、AWTK等大家都熟知的就不介绍了&#xff09;&#xff1a;Avem 项目链接&#xff1a; ht…