【C++】内存管理和模板基础(new、delete、类及函数模板)

    🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm=1010.2135.3001.5343
🔥 系列专栏:http://t.csdnimg.cn/eCa5z

9efbcbc3d25747719da38c01b3fa9b4f.gif

目录

内存分布

C++内存管理方式 

new/delete操作内置类型

 new和delete操作自定义类型

 operator new与operator delete函数

 new和delete的实现原理

内置类型

自定义类型

定位new表达式(placement-new)

malloc/free和new/delete的区别

内存泄漏

 模板

泛型编程

函数模板

模板参数的匹配原则

类模板

定义格式 


前言

    💬 hello! 各位铁子们大家好哇。

             今日更新了内存管理和模板的内容
    🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝

内存分布

 从语言的角度看,数据段叫静态区,代码段叫常量区。从操作系统来看,就叫数据段和代码段。

对于栈来讲,生长方向是向下的,也就是向着内存地址减小的方向;对于堆来讲,它的生长方向是向上的,是向着内存地址增加的方向增长 

说明:

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

 下面来做几道题:

分析: num1是数组名,数组名代表整个数组,数组是在栈上的;“abcd\0”在常量区,char2会在栈上开辟数组,然后把常量区的字符串拷贝到数组中,跟num1一样;*char2是首元素a,a也是在栈上的;const修饰的不代表在常量区,不是常量,只是常变量。pchar3是栈上的指针变量,所以*pchar3指向的是字符串,在常量区;


下面几道不讲解:

C++内存管理方式 

C++通过new和delete操作符进行动态内存管理。

new/delete操作内置类型

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

 new和delete操作自定义类型

注意:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与 free不会。


operator new实际就是对malloc的封装,是给底层用的。就像sizeof是在编译时作用,运行后直接变成底层指令。 

 operator new与operator delete函数

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

operator new和malloc在使用上没啥区别。operator new 实际也是通过malloc来申请空间,如果 malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施 就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。 因为c++要符合面向对象,失败要抛异常,因此用operator new来封装malloc。

 new和delete的实现原理

内置类型

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

自定义类型

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在底层的原理 :

定位new表达式(placement-new)

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

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

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

malloc/free和new/delete的区别

共同点:都是从堆上申请空间,并且需要用户手动释放。

不同点:

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

内存泄漏

内存泄漏指一块不再使用的空间,没有释放。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

 模板

泛型编程

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。

函数模板

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

格式:template <typename T1, typename T2,......,typename Tn>

返回值类型 函数名(参数列表){}

 注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)


如上图,有了模板,编译器就会根据传入的实参生成对应类型的函数。不过以后swap不需要我们自己写了,c++库里面有,我们可以直接用。 


 用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。 

1. 隐式实例化:让编译器根据实参推演模板参数的实际类型

 如上图,因为实参a1和d1是不同类型的,编译器推演时,无法确定T要转成什么类型,就会报错。下面是解决方法。

2. 显式实例化:在函数名后的<>中指定模板参数的实际类型 


模板参数的匹配原则

一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数

对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数,那么将选择模板

模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

类模板

定义格式 


类模板可以让我们更方便写出两个不同数据类型的类。

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<> 中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。 

如上图,Stack类名,Stack<int>才是类型。

注意:类模板中函数放在类外进行定义时,需要加模板参数列表。

如下图:

注意:类模板中的函数不能声明和定义分离到两个不同的文件。

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

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

相关文章

Cesium:绘制一个 3DTiles 对象的外包盒顶点

作者:CSDN @ _乐多_ 本文将介绍如何使用 Cesium 引擎根据模型的中心坐标,半轴信息,绘制一个 3DTiles 对象的外包盒顶点。 外包盒是一个定向包围盒(Oriented Bounding Box),它由一个中心点(center)和一个包含半轴(halfAxes)组成。半轴由一个3x3的矩阵表示,这个矩阵…

Apache Dolphinscheduler - 无需重启 Master-Server 停止疯狂刷日志解决方案

记录的是一个 3.0 比较难搞的问题&#xff0c;相信不少使用过 3.0 的用户都遇到过 Master 服务中存在一些工作流或者任务流一直不停的死循环的问题&#xff0c;导致疯狂刷日志。不过本人到现在也没找到最关键的触发原因&#xff0c;只是看到一些连锁反应带来的结果…… 影响因素…

qmldir的理解

目录结构&#xff1a; 文件内容 qmldir中&#xff1a; module QtLocaion plugin declarative_location classname QtLocationDeclarativeModule typeinfo plugins.qmltypes 其中&#xff1a; QtLocaion必须与qmldir所在的文件夹名字一样 plugin 后面的declarative_location 为…

SHELL——条件判断语句练习

目录 一、练习题目 二、解答过程 1、判断当前磁盘剩余空间是否有20G&#xff0c;如果小于20G&#xff0c;则将报警邮件发送给管理员&#xff0c;每天检查次磁盘剩余空间。 安装邮件服务 配置邮件服务 编写脚本work1.sh 添加计划任务 2、判断web服务是否运行&#xff1a;…

项目中遇到的sql问题记录

有一张表&#xff0c;表结构及数据如下&#xff1a; INSERT INTO test.test_approve(approve_no, tra_date, tablename, part_dt) VALUES (approve001, 2021-02-18 00:00:00, tableA, 2024-03-18); INSERT INTO test.test_approve(approve_no, tra_date, tablename, part_dt) …

【Linux】日常使用命令(三)

文章目录 **cal 命令****date 命令****bc 命令****Linux下玩小游戏**&#xff1a; cal 命令 功能描述: cal 命令用于显示日历。 常用选项: -3&#xff1a;显示前一个月、当前月和下一个月的日历。-y&#xff1a;显示整年的日历。 常用示例: # 示例 1: 显示当前月的日历 cal# …

Easy Connect下载(Windows版)

文章目录 1. 下载连接2. 安装 1. 下载连接 百度网盘链接&#xff1a;https://pan.baidu.com/s/13r4wxz-Df3S_IMruZIDucw  提取码&#xff1a;mmcc 2. 安装 1. 下载安装包解压后&#xff0c;双击.exe文件就可以安装软件。 2. 耐心等待&#xfeff;&#xfeff;Easy Connect安装…

Android 开发环境搭建(Android Studio 安装图文详细教程)

Android Studio 下载 https://developer.android.google.cn/studio?hlzh-cn Android Studio 安装 检查电脑是否启用虚拟化 如果没有开启虚拟化&#xff0c;则需要进入电脑的 BIOS 中开启 直接 next选择安装的组件&#xff0c;Android Studio 和 Android 虚拟设备&#xff…

Gitlab-runner注册与配置

文章目录 概要操作流程获取HTTPS证书上传证书修改gitlab-runner dns配置文件gitlab-runner 注册 概要 本文主要介绍了Gitlab-runner在内网环境注册到gitlab的操作方式。内网环境如下&#xff1a; 1、gitlab-runner由docker镜像部署&#xff1b; 2、gitlab部署与内网&#xff0…

Linux的背景介绍

1.Linux的发展史 Linux&#xff0c;一般指GNU/Linux&#xff08;单独的Linux内核并不可直接使用&#xff0c;一般搭配GNU套件&#xff0c;故得此称呼&#xff09;&#xff0c;是一种免费使用和自由传播的类UNIX操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹&#xff08…

Android studio开发中Virtual Device模拟器的设置和屏幕错位等问题

Android SDK开发中Virtual Device模拟器的设置和使用 本文介绍android studio2023 3.1.13版本中模拟器的设置和在cordova开发中的运行方法 对于老版android studioAVD模拟器的使用&#xff0c;参见&#xff1a;Android SDK手机应用开发中第三方模拟器、真机运行方法以及AVD模拟…

安卓RecyclerView简单用法

废话不多说上代码 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:tools"http://schem…

60+款VSCode插件,构建超舒适开发环境

本文不做任何编辑器的比较&#xff0c;只是我本人日常使用 vscode 进行开发&#xff0c;并且比较喜欢折腾 vscode &#xff0c;会到处找这一些好玩的插件&#xff0c;于是越攒越多&#xff0c;今天给大家推荐一下我收藏的 60 多个 vscode 插件&#xff0c;据说插件装太多&#…

qt+ffmpeg 实现音视频播放(二)之音频播放

一、音频播放流程 1、打开音频文件 通过 avformat_open_input() 打开媒体文件并分配和初始化 AVFormatContext 结构体。 函数原型如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options); 参数说…

Python统计初步

文章目录 基本统计特征区间统计PandaspandasGUI Python科学计算&#xff1a;数组&#x1f4af;数据生成&#x1f4af;数据交互&#x1f4af;微积分&#x1f4af;插值&#x1f4af;拟合&#x1f4af;FFT&#x1f4af;卷积&#x1f4af;滤波 基本统计特征 分析统计特征是数据分…

大规模采集主流电商平台商品详情页获取商品详情,SKU,价格操作流程

taobao API 接入 淘宝接口解析是指通过淘宝提供的API&#xff08;Application Programming Interface&#xff09;来实现程序与淘宝平台的数据交互和功能调用。通过淘宝接口&#xff0c;用户可以实现商品信息获取、订单管理、物流跟踪等功能。 在使用淘宝接口前&#xff0c;首…

BUUCTF-MISC-[QCTF2018]picture

题目链接&#xff1a;BUUCTF在线评测 (buuoj.cn) 解题过程 下载附件发现没有扩展名&#xff0c;用010Editor打开是png图片 保存为png格式打开&#xff1a; BUUCTF平台会缺失一些提示&#xff0c;点开题目链接在GitHub里有题目描述&#xff1a; 提示判断应该是lsb隐写&#xff0…

Javaweb的学习21_CSS_属性

CSS的属性 (常用)属性&#xff1a; 1. 字体、文本 font-size&#xff1a;字体大小 color&#xff1a;文本颜色 text-align&#xff1a;文本的对齐方式 line-height&#xff1a;行高 2. 背景 background&#xff1a;是个复合属性 3. 边框 border&#xff1a;设置边框&#xff0c…

robots协议详解:爬虫也要有边界感

随着互联网的迅猛发展,信息的获取变得越来越便捷,而网络爬虫(Spider)技术就是其中之一。网络爬虫是一种自动化程序,它能够遍历互联网上的网页,提取信息,用于各种用途,例如搜索引擎索引、数据挖掘、价格比较等。但是,爬虫技术虽然强大,但是也是一把双刃剑,在正当使用…

【机器学习300问】38、什么是K-means算法?

在实际工作中&#xff0c;我们经常会遇到这样一类问题&#xff1a;给机器输入大量的特征数据&#xff0c;并期望机器通过学习找出数据存在的某种共性特征、结构或关联。这类问题被称为“非监督学习”问题。这篇文章我就来聚焦非监督学习中的其中一个任务——聚类 例如在数字营销…