99 C++内存高级话题。new/delete的进一步认识 整理

1. new 初始化的整理。

class Teacher120 {
public:Teacher120() {cout << "teacher120 moren 构造函数" << endl;}Teacher120(int age):m_age(m_age) {cout << "teacher120 构造函数" << endl;}~Teacher120() {cout << "teacher120 析构函数" << endl;}int m_age;
};void main() {//1. new 初始化的整理。//对于普通类型int *point = new int;//初值随机int *point1 = new int();// 初值是0.int *point2 = new int(100);// 初值是100.delete point;delete point1;delete point2;//对于自带的类,例如 stringstring* str1 = new string; //初值为""string* str2 = new string();//初值为""string* str3 = new string("abc");//初值为"abc"string* str4 = new string(5,'a');//初值为"aaaaa"int str4len = str4->length(); //大小为5cout << "str4len" << str4len << endl;delete str1;delete str2;delete str3;delete str4;//对于自定义类,需要调用Teacher120的构造函数,//当前Teacher120没有空的构造函数,因此要传参数Teacher120 * pt = new Teacher120(80);delete pt;//  运行结果://  teacher120 构造函数//	teacher120 析构函数//类的集合Teacher120 * pt1 = new Teacher120[3];delete []pt1;//  运行结果://  teacher120 moren 构造函数//	teacher120 moren 构造函数//	teacher120 moren 构造函数//	teacher120 析构函数//	teacher120 析构函数//	teacher120 析构函数//对于集合,先来看正常的vector怎么使用vector<int> a;a.push_back(2);a.push_back(5);cout << a[0] << endl;  //2 vector<int>::iterator it = a.begin();for (; it < a.end();it++) {cout << "  it  = " << *it << endl;}//it = 2//	it = 5//对于集合,指针vector<int> * pv = new vector<int>;pv->push_back(10);pv->push_back(20);pv->push_back(30);for (vector<int>::iterator it1 = pv->begin(); it1 < pv->end();it1++) {cout << "it1 = " << *it1 << endl;}//it1 = 10//	it1 = 20//	it1 = 30delete pv;//对于集合数组,pv2指向一个 三个vector<int> 组成的,我们假设每一个vector中都有5个int 组成。//注意的是:这里 pv 和 pv2 都是前面都是  vector<int> * 类型vector<int> *pv2 = new vector<int>[3];for (size_t i = 0; i < 3; i++){for (int k = 0; k < 5;k++) {pv2[i].push_back(k);}}for (int i = 0; i < 3; i++) {for (vector<int>::iterator it = pv2[i].begin(); it < pv2[i].end();it++) {cout << "   " << *it;}cout << endl;}//0   1   2   3   4//	0   1   2   3   4//	0   1   2   3   4delete[] pv2;char *p = nullptr;delete p;//空指针可以多次deletedelete p;//总结: new 和delete 要成对使用,delete的租用是回收用new 分配的内存}

1.1 new 类对象时 加括号,和不加括号的区别是?

对于普通类型:

    int *point = new int;//初值随机
    int *point1 = new int();// 初值是0.
    int *point2 = new int(100);// 初值是100.

对于自定义类,如果是个空类,类中啥有没有,那么如下两种没有区别

Teacher *ptea = new Teacher;

Teacher *ptea1 =new Teacher();

对于自定义类,如果有成员变量int mage,但是没有自己写的构造函数

Teacher *ptea = new Teacher; //mage是随机值

Teacher *ptea1 =new Teacher(); //mage = 0;

对于自定义类,如果有成员变量int mage,也有自己写的构造函数

Teacher *ptea = new Teacher; //mage是随机值,这是因为编译器认为你既然写了构造函数,就应该在构造函数中完成自己成员的初始化,而不是依赖于我

Teacher *ptea1 =new Teacher(); //mage是随机值,这是因为编译器认为你既然写了构造函数,就应该在构造函数中完成自己成员的初始化,而不是依赖于我

2.new /delete是什么?

关键字/运算符,不是函数

3.new做了两件事:使用反汇编查看干了啥

3.1.分配内存,通过 operator new()函数实现

3.2.调用构造函数初始化内存

class Teacher34 {
public:Teacher34() {cout << "Teacher34 的构造函数被调用" << endl;}~Teacher34() {cout << "Teacher34 的析构函数被调用" << endl;}
};void main(){Teacher34 *ptea = new Teacher34;cout << "duandian zaizheli" << endl;
}

然后在 operator new 这一行按下 F11进去看,就会看到malloc语句

4.delete 做了两件事,使用反汇编查看干了啥

4.1.调用析构函数

4.2.释放内存,通过operator delete()函数显示

class Teacher34 {
public:Teacher34() {cout << "Teacher34 的构造函数被调用" << endl;}~Teacher34() {cout << "Teacher34 的析构函数被调用" << endl;}
};void main(){Teacher34 *ptea = new Teacher34;cout << "11111 11111" << endl;delete ptea;cout << "22222 22222" << endl;ptea = nullptr;cout << "duandian zaizheli" << endl;
}

在delete ptea这一行加上断点,查看这一行到底干了啥?

继续F11

3,4 的另一种验证方法 

ctrl+鼠标点击 进入查看源码,但是只能看到调用了 operator new

5.new/delete  和 malloc() /free()的区别

new 、delete 是关键字/运算符。会调用构造函数/析构函数

malloc(),和 free()是函数。从C 语言继承,没有构造函数/析构函数的概念

6.new 出来的内存多大,delete的时候是怎么知道的呢?

例如

int *p = new int();// new 出来的是int大小 - 4个字节,那么delete 的时候,delete怎么知道要销毁4个字节呢?

new 内部有机制,会记住大小,delete的时候会先通过p的地址查找到这块内存,然后根据这个值删除对应大小的空间

7.关于申请和释放数组的问题

对于基础类型的数组

int *parr = new int[3];

delete [] parr;//如果不释放,就会有3*4 = 12个字节的 内存泄漏

对于自定义类型数组,会多出来4个字节保存数组的大小

class A{

}

假设A 类中啥都没有,那么这个A 类会占用1个字节的大小

那么意味着:

A * arrclass = new A();

delete arrclass; 如果不释放,会有1个字节被泄露。

但是如果自定义类有析构函数,且new 出来的是数组,那么会额外占用4个字节的大小

class B{

        public:

                ~B(){ };

}

B * arrclassBBB = new B[3]();

//如果没有delete [] arrcassBBB 的情况下,会有7个字节的内存泄漏

每个B 泄漏一个,然后还有一个4字节,这4个字节是记录该数组有几个数字,也就是3.因此泄漏7个字节。

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

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

相关文章

hivesql的基础知识点

目录 一、各数据类型的基础知识点 1.1 数值类型 整数 小数 float double(常用) decimal(针对高精度) 1.2 日期类型 date datetime timestamp time year 1.3 字符串类型 char varchar / varchar2 blob /text tinyblob / tinytext mediumblob / mediumtext lon…

CentOS7虚拟机设置静态IP

虚拟机上ip是有时效性的&#xff0c;过期后会自动更换&#xff0c;因此如果想让ip不变&#xff0c;就得手动设置静态ip。 第一步&#xff1a;先查看主机的子网掩码 1.1、windows命令ipconfig&#xff0c;如下图&#xff1a; 第二步&#xff1a;查看虚拟机的网关、ip区间的设…

单臂路由实验(华为)

思科设备参考&#xff1a; 单臂路由实验&#xff08;思科&#xff09; 一&#xff0c;实验目的 在路由器的一个接口上通过配置子接口的方式&#xff0c;实现相互隔离的不同vlan之间互通。 ​ 二&#xff0c;设备配置 Switch1 <Huawei>sys [Huawei]vlan batch 10 20…

【C++】类与对象(三)—运算符重载|const成员函数|取地址及const取地址操作符重载

前言 运算符重载&#xff0c;自增自减运算符重载&#xff0c;const成员函数&#xff0c;取地址及const取地址操作符重载 文章目录 一、运算符重载自增和自减运算符重载 二、const 成员函数三、取地址及const取地址操作符重载&#xff08;了解即可&#xff09; 一、运算符重载 运…

【MySQL】深入理解隔离性

深入理解隔离性 一、数据库并发的场景二、多版本并发控制&#xff08; MVCC &#xff09;三、三个前提知识1、3个记录隐藏字段2、undo日志 四、快照的概念五、Read View六、隔离级别RR与RC的本质区别 一、数据库并发的场景 数据库并发的场景总共有三种&#xff1a; 读-读&…

JVM中一次完整的GC回收流程

JVM堆内存结构简述 JVM堆内存结构图 堆初体验 所有的对象实例以及数组都要在堆上分配&#xff0c;堆是垃圾收集器管理的主要区域&#xff0c;也被称为“GC 堆”&#xff0c;也是我们优化最多考虑的地方。因为在一个项目中&#xff0c;会不断地创建对象&#xff0c;都是在堆里…

DevOps 教程 (4) - CI/CD 整合

在本第四章的"DevOps 教程"系列中&#xff0c;我们将介绍CI/CD整合的概念和实践。我们会介绍DevOps所带来的好处&#xff0c;包括团队协作、开发效率和产品交付速度的显著提升。 我们还将讨论在DevOps中的不同角色&#xff0c;并理解每个角色在持续集成和持续交付中的…

微调实操一: 增量预训练(Pretraining)

1、前言 《微调入门篇:大模型微调的理论学习》我们对大模型微调理论有了基本了解,这篇结合我们现实中常见的场景,进行大模型微调实操部分的了解和学习,之前我有写过类似的文章《实践篇:大模型微调增量预训练实践(二)》利用的MedicalGPT的源码在colab进行操作, 由于MedicalGPT代…

浅压缩、深压缩、双引擎、计算机屏幕编码……何去何从?

专业视听领域尤其显示控制和坐席控制领域&#xff0c;最近几年最激动人心的技术&#xff0c;莫过于分布式了。 分布式从推出之日就备受关注&#xff1a;担心稳定性的&#xff0c;质疑同步性能的&#xff0c;怀疑画面质量的…… 诚然&#xff0c;我们在此前见多了带着马赛克的…

【C++】类和对象1:类的定义、访问限定符、作用域及对象大小

前言 本文主要是简单的介绍一下类是什么、如何使用 类的定义 class className { // 类体&#xff1a;由成员函数和成员变量组成 };// 一定要注意后面的分号class为定义类的关键字&#xff0c;ClassName为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后面…

智慧文旅:驱动文化与旅游融合发展的新动力

随着科技的快速发展和人们生活水平的提高&#xff0c;文化和旅游的融合成为了时代发展的必然趋势。智慧文旅作为这一趋势的引领者&#xff0c;通过先进的信息技术手段&#xff0c;推动文化与旅游的深度融合&#xff0c;为产业的发展注入新的活力。本文将深入探讨智慧文旅如何成…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏9(附项目源码)

本节最终效果演示 文章目录 本节最终效果演示系列目录前言回收物品素材绘制UI代码控制垃圾桶回收功能效果 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇中&#xff0c;我们将…

低成本高效益,电子画册才是品牌的重要选择

​随着互联网的普及和数字化技术的进步&#xff0c;电子画册已成为许多品牌的重要选择。与传统印刷画册相比&#xff0c;电子画册具有低成本、高效益的优点&#xff0c;成为品牌宣传的新趋势。 具体来说&#xff0c;电子画册可以通过在线平台或移动设备轻松查看&#xff0c;无需…

logback自定义生成DB日志(java环境)

目的&#xff1a; 未来在生成日志写入数据库中加一个特殊的字段&#xff0c;官方老版本提供的DBAppender无法实现&#xff0c;并且好巧不巧&#xff0c;在新版本这个实现也被删除了&#xff0c;所以重写一个实现。 1. 安装依赖 安装logback maven依赖 注意&#xff1a; lo…

数据结构——实验01-线性表的链式存储和操作

一、实验内容 二、算法思想与算法实现 1、解题思想 &#xff08;1&#xff09;逆序创建链表La就是使用头插法创建一个链表&#xff0c;所谓头插法就是在创建链表时始终将新元素插入到头结点之后&#xff0c;而正序创建链表Lb就是使用尾插法创建一个链表&#xff0c;所谓尾插法…

[高阶·产品经理]业务建模和需求高阶2月26-3月1日晚8点

等级 高阶 介绍 软件开发中&#xff0c;需求是解决“系统怎样好卖”的问题&#xff0c;设计是解决“降低开发成本”的问题。 本训练聚焦第一个方面&#xff0c;在点上强化业务建模和需求的技能。每期的教材都会根据当期学员所整理的学习《软件方法》的过程中以及工作中碰到的…

conda虚拟环境基础

【一文搞定最新版Anaconda】Win11 安装 Anaconda&#xff08;2023.9&#xff09;详解&#xff08;不删除旧版情况下下载、安装、注册、登录、设置环境变量、迁移旧环境、配置修改换源等&#xff09;连接Pycharm_win11安装anaconda-CSDN博客 conda命令大全&#xff08;create/in…

产品经理必备知识——API接口(获取电商商品订单数据API)

前言 在古代&#xff0c;我们的传输信息的方式有很多&#xff0c;比如写信、飞鸽传书&#xff0c;以及在战争中使用的烽烟&#xff0c;才有了著名的烽火戏诸侯&#xff0c;但这些方式传输信息的效率终究还是无法满足高速发展的社会需要。如今万物互联的时代&#xff0c;我通过…

网络安全之漏洞扫描

漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷&#xff0c;从而可以使攻击者能够在未授权的情况下访问或破坏系统。这些缺陷、错误或不合理之处可能被有意或无意地利用&#xff0c;从而对一个组织的资产或运行造成不利影响&#xff0c;如信息系统被攻击或控制…

关于node.js奇数版本不稳定 将11.x.x升级至16.x.x不成功的一系列问题(一)

据说vue2用16稳定一些 vue3用18好一点&#xff08;但之前我vue3用的16.18.1也可以&#xff09; 为维护之前的老项目 先搞定node版本切换 下载nvm node版本管理工具 https://github.com/coreybutler/nvm-windows/releases 用这个nvm-setup.zip安装包 安之前最好先将之前的nod…