【C++动态内存管理】

news2024/9/21 4:33:09

目录

  • 一、C/C++内存分布
  • 二、C++中动态内存管理
    • 2.1new/delete操作内置类型
    • 2.2new/delete操作自定义类型
  • 四、new和delete的实现原理
    • 4.1内置类型
    • 4.2自定义类型
  • 五、 定位new表达式(placement-new)
  • 六、总结

一、C/C++内存分布

一张图重温一下C/C++内存分布。
在这里插入图片描述

二、C++中动态内存管理

C++中的动态内存管理需要用到关键字new、delete。

2.1new/delete操作内置类型

#include<iostream>
using namespace std;
int main()
{
	//动态申请一个整形的空间,没有初始化
	int* ptr1 = new int;
	//动态申请一个整形的空间,并初始化成10
	int* ptr2 = new int(10);
	//动态申请10个整形空间大小的数组,没有初始化
	int* ptr3 = new int[10];
	//动态申请10个整形空间大小的数组,全部初始化成0
	int* ptr4 = new int[10]{0};

	delete ptr1;
	delete ptr2;
	delete[] ptr3;
	delete[] ptr4;
	return 0;
}

在这里插入图片描述

2.2new/delete操作自定义类型

#include<iostream>
using namespace std;
class Vector
{
public:
	Vector()
	{
		cout << "Vector()默认构造函数调用" << endl;
	}
	Vector(int size,int capacity)
	{
		Size = size;
		Capacity = capacity;
		Arr = new int[Capacity] {0};
		cout << "Vector()有参构造函数调用" << endl;
	}
	~Vector()
	{
		cout << "~Vector()析构函数调用" << endl;
	}
private:
	int Size;
	int Capacity;
	int* Arr;
};
int main()
{
	Vector* ptrV1 = new Vector;
	delete ptrV1;
	return 0;
}

在这里插入图片描述
由上图可见new会调用自定义的构造函数、delete会调用自定义的析构函数。
所以在一些场景下大大方便了我们代码的编写。比如下图:
在这里其实已经初见new/delete相比于malloc/free的优势了。不过还不够明显。下面的会跟明显。
new在初始化的时候特别的灵活。比如:

#include<iostream>
using namespace std;
class A
{
public:
	A(int val)
	{
		cout << "有参构造函数调用" << endl;
		Val1 = val;
	}
	A(const A& a)
	{
		cout << "拷贝构造函数调用" << endl;
		Val1 = a.Val1;
	}

private:
	int Val1;
};
int main()
{
	//方式1
	A* a1 = new A(10);
	//方式2
	A* a2 = new A[10]{ 1,2,3,4,5,6,7,8,9,10 };
	//方式3
	A* a3 = new A[6]{ A(1),A(2),A(3),A(4),A(5),A(6) };
	return 0;
}

四、new和delete的实现原理

4.1内置类型

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

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

五、 定位new表达式(placement-new)

定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
使用格式:
new (place_address) type或者new (place_address) type(initializer-list)
place_address必须是一个指针,initializer-list是类型的初始化列表

#include<iostream>
using namespace std;
class Vector
{
public:
	Vector()
	{
		cout << "Vector()默认构造函数调用" << endl;
	}
	Vector(int size,int capacity)
	{
		Size = size;
		Capacity = capacity;
		Arr = new int[Capacity] {0};
		cout << "Vector()有参构造函数调用" << endl;
	}
	~Vector()
	{
		cout << "~Vector()析构函数调用" << endl;
	}
private:
	int Size;
	int Capacity;
	int* Arr;
};
int main()
{
	//Vector* ptrV1 = new Vector;
	//delete ptrV1;
	//Vector* ptrV2 = new Vector(0, 4);
	//delete ptrV2;
	Vector* ptrV3 = (Vector*)malloc(sizeof(Vector));
	Vector* ptrV4 = (Vector*)malloc(sizeof(Vector));
	new(ptrV3)Vector;
	new(ptrV4)Vector(0,4);

	ptrV3->~Vector();
	ptrV4->~Vector();

	
	return 0;
}

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

六、总结

malloc/free和new/delete的区别

1.malloc和free是函数,new和delete是操作符。(operator new/operator new[]、delete/delete[])
2.malloc申请的空间不会初始化,new可以初始化,而且初始化的方式特别的灵活。
3.malloc的返回值为void*,在使用时必须强转,new不需要,因为new后面跟的是空间类型。
4.malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常。
5.申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理。

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

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

相关文章

计算物理专题:高维Romberg数值积分方法

有话无话&#xff0c;先上代码&#xff0c;正确与否&#xff0c;先给结论&#xff0c;可信有无&#xff0c;先出文献计算物理&#xff0c;傅哥最强 真计算还得看SCU物拔&#xff08;不是&#xff09;&#xff08;狗头&#xff09;&#xff08;骄傲&#xff09;这种方法的思想是…

Springboot +Flowable,会签、或签简单使用(三)

一.简介 **会签&#xff1a;**在一个流程中的某一个 Task 上&#xff0c;这个 Task 需要多个用户审批&#xff0c;当多个用户全部审批通过&#xff0c;或者多个用户中的某几个用户审批通过&#xff0c;就算通过。 例如&#xff1a;之前的请假流程&#xff0c;假设这个请假流程…

【笔试强训选择题】Day15.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01; 文章目录 前言 一、…

Linux Shell 实现一键部署二进制Python

python 前言 Python由荷兰数学和计算机科学研究学会的吉多范罗苏姆于1990年代初设计&#xff0c;作为一门叫做ABC语言的替代品。 Python提供了高效的高级数据结构&#xff0c;还能简单有效地面向对象编程。Python语法和动态类型&#xff0c;以及解释型语言的本质&#xff0c;使…

监控知识体系

从来没讲过运维&#xff0c;因为我觉得运维这种东西不需要太多的知识面&#xff0c;然后我一个做了运维朋友告诉我大错特错&#xff0c;他就是从3K的运维一步步到40K的&#xff0c;甚至笑着说&#xff1a;我现在感觉自己什么都能做。 既然讲&#xff0c;就讲最重要的吧。 监控…

接口自动化测试分层设计与实践总结

本文以笔者当前使用的自动化测试项目为例&#xff0c;浅谈分层设计的思路&#xff0c;不涉及到具体的代码细节和某个框架的实现原理&#xff0c;重点关注在分层前后的使用对比&#xff0c;可能会以一些伪代码为例来说明举例。 接口测试三要素&#xff1a; 参数构造 发起请求&a…

NA、商业和分销市场通盘布局,华为“四大角色”浮出水面

作者 | 曾响铃 文 | 响铃说 数字经济深化发展&#xff0c;谋求数字化转型的行业、企业客户&#xff0c;越来越渴望满足自身需求的产品或解决方案。 这给从事转型服务的ICT厂商们提出了新的挑战。 在客户面前&#xff0c;拥有核心技术与支持能力的企业&#xff0c;与进击数字…

yolov1

1、对precision&#xff08;精确度&#xff09;和recall&#xff08;召回度&#xff09;的理解 1、TP TN FP FN的概念 TP&#xff08;True Positives&#xff09;意思就是被分为了正样本&#xff0c;而且分对了。 TN&#xff08;True Negatives&#xff09;意思就是被分为了负…

原装美国Agilent安捷伦34970A数据采集仪

Agilent安捷伦34970A数据采集仪 3槽主机&#xff0c;内置GPIB和RS232接口 6 1/2 位&#xff08;22 位&#xff09;内部 DMM&#xff0c;每秒扫描多达 250 个通道&#xff08;选件 001 不可用&#xff09; 8个开关和控制插件模块可供选择 内置信号调理可测量热电偶、RTD 和热敏电…

linux基础(IO)中

目录&#xff1a; 1.回顾上一篇的文件系统调用接口 2.返回值文件描述符 3.文件描述符分配规则 ---------------------------------------------------------------------------------------------------------------------------- 1.回顾上一篇的文件系统调用接口 open &…

【数据结构】二叉树进阶题目练习

文章目录 二叉树创建字符串二叉树的分层遍历1二叉树的分层遍历2给定一个二叉树, 找到该树中两个指定节点的最近公共祖先二叉树搜索树转换成排序双向链表二叉树展开为链表根据一棵树的前序遍历与中序遍历构造二叉树根据一棵树的中序遍历与后序遍历构造二叉树二叉树的前序遍历 非…

学爬虫,吃牢饭,卑微前端小丑复制antd的icon图标真的太难啦,我用python几秒扒完

目标需求 最近用reactviteantd写了个后管项目&#xff0c;在菜单管理中&#xff0c;需要用户选择菜单的icon图标。 如下&#xff1a; 而在react中使用antd UI库&#xff0c;每个组件都是需要单独导入的&#xff0c;也就是说&#xff0c;如果我要用到所有icon&#xff0c;我需…

亚马逊云科技进一步加快BMW Group的Analytics步伐

BMW Group和亚马逊云科技于2020年宣布达成全面战略合作。本次合作的目标是通过将数据分析置于决策中心&#xff0c;进一步加快BMW Group的创新步伐。本次合作的一个关键要素是进一步开发BMW Group的云数据中心&#xff08;CDH&#xff09;。这是在云端管理全公司数据和数据解决…

windows_exporter 部署

目录 - 配置服务- 配置prometheus - 配置服务 下载地址&#xff1a; https://github.com/prometheus-community/windows_exporter/releases 从github上下载windows_exporter.msi&#xff08;我下载的是windows_exporter-0.22.0-amd64.msi&#xff09;cmd命令&#xff1a;msie…

对 API 中敏感数据检测,用这个插件就好了

Postcat 中的 openDLP 插件基于 openDLP 开源项目&#xff0c;针对 Postcat 场景实现了敏感 API 发现功能&#xff0c;通过扫描 API 文档&#xff0c;识别该 API 是否可能是一个涉及敏感数据的 API。 目前内置支持 17 类敏感数据类型&#xff0c;可以通过自定义正则支持更多类型…

2023年安全岗秋招经验分享,纯干货,建议收藏!

需要准备的几个方向 简历自我介绍计算机网络操作系统&#xff08;操作系统原理&#xff0c;Linux&#xff0c;Windows&#xff09;数据库算法&#xff08;Leetcode&#xff09;编程语言&#xff08;Python,C,go等&#xff09;安全知识&#xff08;很多很杂&#xff0c;建议根据…

python3 爬虫相关学习3:response= requests.get(url)的各种属性

目录 1 requests.get(url) 的各种属性&#xff0c;也就是response的各种属性 2 下面进行测试 2.1 response.text 1.2 response.content.decode() 1.2.1 response.content.decode() 或者 response.content.decode("utf-8") 1.2.2 response.content.decode(…

实验室信息管理系统源码,LIS系统源码

云LIS系统是医院信息管理的重要组成部分之一&#xff0c;系统集申请、采样、核收、计费、检验、审核、发布、质控、查询、耗材控制等检验科工作为一体的网络管理系统。LIS系统不仅是自动接收检验数据&#xff0c;打印检验报告&#xff0c;系统保存检验信息的工具&#xff0c;而…

平抑风电波动的电-氢混合储能容量优化配置(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

22届硕士,去年秋招拿了字节跳动offer,有一说一,不是很难进

自从抖音短视频APP火了之后&#xff0c;起公司字节跳动也逐渐向着大厂靠拢&#xff0c;相信大家都已经对这家公司很熟悉了&#xff0c;尤其是近几年来&#xff0c;对它的认识也在不断刷新&#xff0c;它惊人的发展速度确实让行业内人刮目相看&#xff0c;如今很多年轻人也想要挤…