C++语法·叭

          阁下何不乘风起,扶摇直上九万里。       qi fei

4ee7a40c5eb64825b16caa45d2360372.jpeg        

 

目录

内存管理

分区介绍

1.栈区:

2.内存映射段:

3.堆:

4.数据段:

5.代码段:

补充:

C内存管理(简略回忆)

C++内存管理

new(开辟空间) delete(释放空间)

内置类型

自定义类型

异常

operator new 与 operator delete函数

operator new

operator delete

补充QeQ

匹配问题

定位new

总结

malloc/free和new/delete的共同点为:

不同点:

小知识


 

内存管理

分区介绍

acb1cccd10364127ae8b367f926c04d2.png

1.栈区:

又叫堆栈,存放非静态局部变量/函数参数/返回值等等,栈相对来说是向下增长的。

2.内存映射段:

是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享来共享内存,做进程间通信(这个比较复杂,现在先不展开,了解即可)

3.堆:

用于程序运行时动态分配内存,堆是可以向上增长的。

4.数据段:

储存全局数据和静态数据

5.代码段:

可执行的代码/只读常量

补充:

栈区的空间较小,而堆区的空间很大。

C内存管理(简略回忆)

C语言中,内存管理总共有四种函数,malloc、calloc、realloc、free。

其中malloc和calloc是开辟空间的函数,malloc开辟时不会对开辟的空间进行初始化,calloc开辟时会将开辟的空间按内存置0,记得开辟较大空间时要检查是否开辟成功。

realloc作用是扩容,只能对malloc或calloc开的空间进行扩容,分为原地扩容和异地扩容。

原地扩容:如果在原来开辟的空间后有足够的空间,就会返回原地址,叫原地扩容。

异地扩容:如果在原来开辟的空间后没有足够的空间,就会一块新空间,将原空间数据拷贝过来,然后释放原空间,返回新地址,叫异地扩容。

free是释放,只能释放动态开辟的空间,记得每次动态开辟后要进行释放,否则可能会造成内存泄漏。(虽然一般程序结束时操作系统也会回收内存,在程序运行时会有内存泄漏等诸多问题)

------------------------------------

C++内存管理

new(开辟空间) delete(释放空间)

在C语言中,动态开辟空间需要计算字节大小,而C++中不需要。

内置类型

d484f2b7c04a415994068a3c68be3e5e.png

p1为一个int大小的空间 ,new + 类型

p2一个大小为5的数组, [n]为要开辟n个

p3为一个int大小的空间,并初始化为5, (n)为要初始化的值

p4为一个大小为8的数组,并进行初始化, { } 用来连续初始化,如果未给足够的初始化值,则无对应值的位置置为0

注:1.new出来的空间默认是不会初始化的。

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

自定义类型

new和delete对于自定义类型会先开空间然后调用默认构造函数来初始化,没有默认构造会报错。

6be881aafc7e49508f4afbc5679c6016.png

b1b04ea46d54403f8887ba0b16fe2990.png

对于连续多个类型初始化要用{(),(),()}来初始化,只用()要么为一个参数要么为逗号表达式还是一个参数。

364aeee4618a46a5bfc7f7744d84d975.jpeg

异常

new开辟失败后不会像malloc和calloc一样返回空指针,而是抛出一个异常,而异常必须被捕获,否则会报错,使用try + catch来捕获,这个捕获也比较复杂,所以暂且搁置,以后会总结到。

operator new 与 operator delete函数

这两个函数是系统提供的全局函数,不是重载,new在底层通过调用operator new来申请空间,delete在底层通过调用operator delete来释放空间。

operator new

其实这个函数使用的是malloc来开辟空间

operator delete

其实这个函数使用的是free释放空间

所以它们就是malloc和free的封装,在malloc的基础上将开辟失败返回空指针改为了抛异常。

补充QeQ

new单个自定义类型空间时:new = operator new + 默认构造函数 

连续个时:new = operator new循环 + 多个默认构造函数

delete单个自定义类型空间时:delete = 析构函数 + operator delete 

连续个时:delete = 多个析构函数 + operator delete循环

匹配问题

匹配指malloc和free匹配,new和delete匹配,连续空间和连续空间匹配,单个空间和单个空间匹配。

强调:

如果乱搭配不一定会报错,对于内置类型乱搭配很少会有错误,但对于自定义类型来说,就会导致不少错误。  (不过建议最好搭配使用,既清晰也方便他人观看)

自定义类型推荐使用new和delete,方便快捷,但要在开辟连续空间时用匹配的delete来释放,因为只用delete是只会调用析构一次,然后就释放了,但构造函数会在operator new开辟的空间进行对象的初始化,这些空间需要自定义类型自己的析构函数才能正确释放,所以new的空间就不能被正确的释放,导致内存泄漏。

在VS及某些编译器上,new在自定义类型时,会多开几个字节的空间放在最前方,但返回的还是要开的大小的空间的首地址,那么,这几个字节空间用来存什么呢,存的是要开的对象个数,也就是[ ]中的数值,用来告诉与它匹配的delete[ ]析构的次数,因为new了多少个对象就构造了多少,自然就要析构多少。   

总结下:new和delete匹配,operator new一下,构造一下, 然后析构一下,operator delet一下。

new[ ]和delete[ ]匹配,operator new 循环,构造N下,然后析构N下,operator delete 循环,

完美释放,无内存泄漏。

定位new

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

a7cce4f341974a549abb03e8aa51ccbd.png

就像是定位到p1这个空间去进行构造。

但其实平常我们要实例化一个对象只需直接用new 类型  就好了,定位new不用在这里。

谈到定位new的使用场景,就要提到池化技术(内存池、线程池、连接池等),像内存池就是向操作系统要一块未初始化的空间,用来供给使用,定位new正好用在这里。

内存池简介:对于要频繁申请空间的时候,一次申请一大块空间,作为一个储蓄池,让每次使用时都能从这个池子里申请,而不是频繁的向操作系统申请,降低效率。

------------------------------------

总结

malloc/free和new/delete的共同点为:

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

不同点:

1.malloc和free是函数,而new和delete是操作符。


2.malloc申请的空间不会初始化,new是可以去初始化。


3.malloc申请空间时,需要手动计算大小并传过去,new不需要,new只需在后面跟上空间的类型,如果是多个对象,[ ]中指定对象个数即可。


4.malloc的返回值为void* ,在使用时要强制转化,new不需要,因为new已经给类型并且按照类型开空间了。


5.malloc申请空间失败时,返回的是NULL,因此使用时要assert断言判空或if语句+perror判空,但new不会返回NULL,只会抛异常,只需要捕获异常。


6.申请自定义类型空间时,malloc只能开辟空间,而new既可以开辟空间,又可以调用自定义类型的析构函数进行对象的初始化;free只能释放空间,而delete既可以调用自定义类型的析构函数将对象析构,完成空间中资源的正确清理,又可以将空间释放。

小知识

1.四年一闰,百年不闰,四百年又一闰,为什么天数有差距呢,因为一年实际测算又365天5小时48分46秒,为了补齐天数,每四年加一天,也就是在二月加了一天,但因为它不是正好比365天多6小时,所以四年加一天还是不够,就百年再加一天,而百年加一天加多了,就四百年不加。

2.编译器可能会对无意义的代码进行优化,不去执行它。比如:a+b; 不用变量接收,也不进行操作,就是无意义。编译器直接忽略不管。

 

 

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

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

相关文章

elasticsearch单节点模式部署

原文地址:elasticsearch单节点模式部署 – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 第一步:下载 官方下载地址:Download Elasticsearch | Elastic,可以 wget 直接下载。 命令:wg…

【北京迅为】iTOP-4412全能版使用手册-第二十章 搭建和测试NFS服务器

iTOP-4412全能版采用四核Cortex-A9,主频为1.4GHz-1.6GHz,配备S5M8767 电源管理,集成USB HUB,选用高品质板对板连接器稳定可靠,大厂生产,做工精良。接口一应俱全,开发更简单,搭载全网通4G、支持WIFI、蓝牙、…

Spring AOP相关知识详解

难 文章目录 1.AOP介绍1.1 面向切面编程 - Aspect Oriented Programming (AOP)1.2 优点 2.AOP的概念2.1 连接点、切入点、通知、切面:2.2 注解2.2.1 通知类型2.2.1.1 通知的优先级排序 2.2.2 其他重要注解2.2.3 示例代码(四种通知) 3.Spring …

外包干了3年,技术退步明显...

先说情况,大专毕业,18年通过校招进入湖南某软件公司,干了接近6年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能…

【阅读记录-章节4】Build a Large Language Model (From Scratch)

文章目录 4. Implementing a GPT model from scratch to generate text4.1 Coding an LLM architecture4.1.1 配置小型 GPT-2 模型4.1.2 DummyGPTModel代码示例4.1.3 准备输入数据并初始化 GPT 模型4.1.4 初始化并运行 GPT 模型 4.2 Normalizing activations with layer normal…

C7.【C++ Cont】范围for的使用和auto关键字

目录 1.知识回顾 2.范围for 格式 使用 运行结果 运行过程 范围for的本意 作用 注意 3.底层分析范围for的执行过程 反汇编代码 分析 4.auto关键字 格式 基本用法 在范围for中使用auto 1.知识回顾 for循环的使用参见25.【C语言】循环结构之for文章 2.范围for C…

【数据结构】双向链表、单向循环链表、双向循环链表、栈、链栈

目录 一、双向链表 定义类和封装函数以及测试样例如下: 注意事项: 二、循环链表 单循环列表的类和函数封装如下: 注意事项: 三、双向循环链表 结点类和双循环链表的定义部分 函数封装之判空和尾插 双循环链表遍历 双循…

ModuleNotFoundError: No module named ‘_ssl‘ centos中的Python报错

1、检查系统有没有openssl,有的话,就是python安装时没有指定openssl openssl version,有输出版本号就有,没有的话,需要手动安装 下载地址 参见https://www.openssl.org/,包括以下版本: https:/…

C语言:树

在C语言中,树(Tree)是一种常见的数据结构,用于表示分层关系或层次结构的数据集合。树在计算机科学中广泛应用,包括但不限于文件系统、解析表达式、数据压缩、决策树等。 1. 基本概念 节点(Node&#xff0…

python写的服务,用docker制作镜像并且打包

步骤1 简单写一个python服务脚本app.py,通过http访问一个端口,收到helloworld from flask import Flask, request app Flask(__name__) app.route(/, methods[GET]) # 确保包括GET方法 def hello_world(): return Hello, World! if __name__ __main…

NSSCTF web刷题

1 虽然找到了flag,但是我要怎么去改他的代码,让他直接输出flag呢? (好像是要得到他的json代码,这题不让看) 2 wllm应该就是他的密码,进入许可了 意思是服务器可以执行通过POST的请求方式传入参数为wllm的命令,那这就是典型的命令执行,当然&#xff0c…

(0基础保姆教程)-JavaEE开课啦!--11课程(初识Spring MVC + Vue2.0 + Mybatis)-实验9

一、什么是Spring MVC? Spring MVC 是一个基于 Java 的 Web 框架,遵循 MVC 设计模式,用于构建企业级应用程序。它通过控制器(Controller)处理用户请求,模型(Model)处理业务逻辑,视图(View)展示数据,实现了请…

FCBP 认证考试要点摘要

理论知识 数据处理与分析:包括数据的收集、清洗、转换、存储等基础操作,以及数据分析方法,如描述性统计分析、相关性分析、数据挖掘算法等的理解和应用 。数据可视化:涉及图表类型的选择与应用,如柱状图、折线图、饼图…

「Qt Widget中文示例指南」如何为窗口实现流程布局?(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 本文将展示如何为不…

智能产品综合开发 - 手势识别

1 实训选题目的 本次实训选择的题目是“基于树莓派的手势识别系统”,旨在为人们提供一种便捷的交互方式,使用户能够通过手势控制智能设备,摆脱传统的物理按键操作。通过本项目,我们希望能实现快速、灵活的手势识别,提升…

Redis【1】- 如何阅读Redis 源码

1 Redis 的简介 Redis 实际上是简称,全称为 Remote Dictionary Server (远程字典服务器),由 Salvatore Sanfilippo 写的高性能 key-value 存储系统,其完全开源免费,遵守 BSD 协议。Redis 与其他 key-value 缓存产品(如…

git的使用(简洁版)

什么是 Git? Git 是一个分布式版本控制系统 (DVCS),用于跟踪文件的更改并协调多人之间的工作。它由 Linus Torvalds 在 2005 年创建,最初是为了管理 Linux 内核的开发。Git 的主要目标是提供高效、易用的版本控制工具,使得开发者…

用于高吞吐量和低延迟的 JVM 性能调优

Java 虚拟机 (JVM) 调优是调整默认参数以满足我们的应用程序需求的过程。这包括通过选择合适的垃圾回收器来使用优化版本的 getter 来调整堆的大小等简单调整。 了解 Java 虚拟机 (JVM) 什么是 JVM? Java 虚拟机 &…

django authentication 登录注册

文章目录 前言一、django配置二、后端实现1.新建app2.编写view3.配置路由 三、前端编写1、index.html2、register.html3、 login.html 总结 前言 之前,写了django制作简易登录系统,这次利用django内置的authentication功能实现注册、登录 提示&#xff…

Python+Pytest+Yaml+Allure数据参数化(DDT)数据驱动(一)

我们在做数据之前要知道几个问题 1、在代码层面怎么来数据驱动 2、yaml文件是什么 3、怎么用yaml文件实现对应的数据驱动 我们用的是pytest框架所以相对来说是简单的,我们通过pytest框架来实现,而框架中要数据驱动用到我们装饰器就好啦pytest.mark.p…