03.C++内存管理笔记

1、C/C++内存分布

①内存分那么多区的原因:不同的数据,有不同的存储需求,各区域满足了不同的需求。

②存放:

临时变量等临时用的变量:栈区;

动态申请的变量:堆区;

全局变量和静态变量等整个程序期间都使用的变量:数据段;

常量、可执行代码等只读数据:代码段;

2、C语言中动态内存管理方式:malloc/calloc/realloc/free

3、C++内存管理方式

C语言的内存管理方式在C++中依然可以使用但是有些情况不方便,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

①new/delete操作内置类型

1°new操作符

动态开辟一个整型:

int* p=new int;

动态开辟一个整型同时赋个初值:

int* p=new int(3);

动态开辟多个整型:

int* p=new int[10];

动态开辟多个整型同时赋值:

int* p=new int[10]{1,2,3};

2°delete操作符

释放申请的一个空间:

delete p;

释放申请的多个空间:

delete[] p;

★new和delete,new[]和delete[]匹配起来使用;

★对于内置类型,malloc和new除了用法上的区别,没有别的区别;

②new/delete操作自定义类型

C语言的动态管理对于自定义类型是不好解决初始化的,所以必须要使用C++提供的new和delete

1°new操作符

动态开辟一个自定义类型:

A* p=new A;       //A是一个自定义的类

动态开辟一个自定义类型同时赋初值:

A* p=new A(1);       //自定义类型有传一个整型的构造函数

动态开辟多个自定义类型:

A* p=new A[3];          //开辟三个自定义类型的对象

动态开辟多个自定义类型同时赋初值:

A* p=new A[3]{1,2,3};         //隐式类型转换赋初值
A* p=new A[3]{aa1,aa2,aa3};     //利用已有的对象赋初值
A* p=new A[3]{A(1),A(2),A(3)};           //用匿名对象赋初值

★new的本质:开空间+调用构造函数初始化

2°delete 

释放申请的一个空间:

delete p;

释放申请的多个空间:

delete[] p;

★delete的本质:调用析构函数+释放空间

③new失败

1°new失败的话会抛出异常,但是异常需要捕获;

2°cout打印char*类型的数据的时候,默认打印的是字符串类型,想要打印地址可以使用printf或者前面加(void*)强制类型转换

4、operator new与operator delete函数

①new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层调用operator delete全局函数来释放空间。(这两个函数不是对new和delete的重载)

②operator new和operator delete封装的malloc和free。malloc失败了返回0,operator new失败了抛异常,这样更符合面向对象的特性。operator delete是为了和operator new配对。

5、new和delete的实现原理

①new和delete是操作符,运行时new直接转换成汇编指令,汇编指令中调用了operator new之后调用构造函数,delete直接转换成汇编指令,汇编指令中调用了析构函数之后,调用operator delete。

即:

new的原理:调用operator new函数申请空间

                     在申请的空间上执行构造函数,完成对象的构造

delete的原理:在空间上调用析构函数,完成对对象资源的清理工作

                        调用operator delete函数完成对象空间的释放

new[]的原理:调用1次operator new[]函数申请N个对象的空间   

                       在申请的空间上执行N次构造函数,完成对象的构造

                       ★开空间时会在空间的头部多开四个字节的空间。

                       ★多开四个字节空间是为了告诉delete[]调用析构函数时调用几次

delete[]的原理:在空间上调用N次析构函数,完成对对象资源的清理工作

                          调用1次operator delete函数完成对象空间的释放

                          ★释放空间时会向前减四个字节开始释放空间

▲如果使用new[]申请空间,使用delete释放空间,逻辑上一定是错的,但是可是报错,可能不报错。报错是因为,new[]申请空间时在空间的前面多申请了四个字节的空间,delete释放是没有从四个字节前开始释放,相当于从中间开始释放的,这是肯定会报错的。不报错的话,就是因为你的类没有显式的写析构函数,并且你的成员变量都是内置类型,new[]申请空间时前面没有多申请前面四个字节的空间,所以使用delete释放也是可以的,但是这属于编译器的优化,是编译器做的,不一样的编译器不一定做法相同。所以写的时候一定要注意匹配的问题。

6、定位new表达式(placemen-new)

①构造函数和析构函数都可以显式调用,析构函数像调用普通函数一样直接调用就好了,而构造函数像普通函数一样直接调用会报错,需要使用定位new来进行显式调用。

②定位new显式调用构造函数的主要场景:

一般定位new都是和内存池一起配合使用的,我们频繁去堆开辟一小块空间是效率非常低的,所以有了内存池的概念,内存池就是一次在堆中申请一块比较大的空间,然后我们创建对象时先去内存池看看空间够不够,空间不够就去堆中开辟,空间够就直接使用内存池内的空间,而内存池的空间是以前开辟的,所以是未初始化的,我们想要初始化就需要使用定位new来显式调用构造函数。

③使用格式:

new(place_address) type 或者new(place_address) type (Initializer_list)

place_address:必须是一个指针

initializer_list:是类型的初始化列表

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

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

相关文章

Python图形界面开发:Tkinter与PyQt

Python是一种非常流行的编程语言,它拥有丰富的图形用户界面(GUI)开发库。其中,Tkinter和PyQt是最常用的两个库。下面是对这两个库的简单介绍。 1. Tkinter Tkinter是Python的标准图形用户界面库。它提供了一组简单的工具和函数&…

人工智能:现状与未来发展

人工智能(Artificial Intelligence, AI)作为一门前沿科技,近年来取得了长足的发展,给我们的生活带来了巨大的改变。目前,人工智能已经广泛应用于各个领域,不论是医疗、交通、金融还是教育等,都能…

Python从入门到精通秘籍二

Python速成,知识点超详细,跟着这个系列边输入边学习体会吧! 一、Python的标识符 在Python中,标识符是用来命名变量、函数、类、模块等的名称。下面是一些使用代码示例来详细说明Python的标识符的具体规则和用法: 1.标识符的命名规则: 可以包含字母(大小写)、数字和下…

433. 最小基因变化(Queue使用ArrayList和LinkedList进行声明)

这道题可以看成一个24叉树。 因为基因序列长度固定为8,且每个位置的字母固定是AGCT,可以选择改变的只有3个字母,所以一次最多24种情况。 然后检查变化后的结果是否存在bank中(使用hashSet来存储),同时设置…

GO语言Context的作用

文章目录 Context为什么需要Context多任务超时例子Context结构 Context各种使用方法创建contextvalueCtxvalueCtx结构体WithValue cancelCtxcancelCtx结构体withCancel timerCtxWithDeadlineWithTimeout 总结 Context 为什么需要Context Go语言需要Context主要是为了在并发环…

初识C语言·内存函数

1 memcpy的使用和模拟实现 紧接字符串函数,出场的是第一个内存函数memcpy。前面讲的字符串函数是专门干关于字符串的事的,而这个函数可以干strcpy一样的事,但是区别就是它碰到\0也会继续复制。 函数的头文件是string,返回类型是v…

如何从 Keras 中的深度学习目录加载大型数据集

一、说明 数据集读取,使用、在磁盘上存储和构建图像数据集有一些约定,以便在训练和评估深度学习模型时能够快速高效地加载。本文介绍Keras 深度学习库中的ImageDataGenerator类等工具自动加载训练、测试和验证数据集。 二、ImageDataGenerator加载数据集…

2024.1.11

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);speechnew QTextToSpeech(this);id1startTimer(1000);//设置文本到中间ui->sys_label->setAlignment(Qt:…

20240107移远的4G模块EC20在Firefly的AIO-3399J开发板的Android11下调通能上网

20240107移远的4G模块EC20在Firefly的AIO-3399J开发板的Android11下调通能上网 2024/1/7 11:17 开发板:Firefly的AIO-3399J【RK3399】SDK:rk3399-android-11-r20211216.tar.xz【Android11】 Android11.0.tar.bz2.aa【ToyBrick】 Android11.0.tar.bz2.ab …

Java的Netty

1.基本概念介绍 有了Netty,你可以实现自己的HTTP服务器,FTP服务器,UDP服务器,RPC服务器,WebSocket服务器,Redis的Proxy服务器,MySQL的Proxy服务器等等。 Netty 是一个基于 Java 的高性能网络应…

红队打靶练习:BREACH: 1

信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:69:c7:bf, IPv4: 192.168.110.128 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.110.1 00:50:56:c0:00:08 …

RK3568驱动指南|第十篇 热插拔-第118章 使用udev挂载U盘和T卡实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…

CTF-PWN-沙箱逃脱-【seccomp和prtcl-1】

文章目录 啥是seccomp#ifndef #define #endif使用使用格式 seccomp无参数条件禁用系统调用有参数条件禁用系统调用 prctl实例 seccomp_export_bpf 啥是seccomp 就是可以禁用掉某些系统调用,然后只能允许某些系统调用 #ifndef #define #endif使用 #ifndef #defin…

Day4Qt

1.头文件: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTime>//时间类 #include <QTimer>//时间事件类 #include <QTimerEvent>//定时器类 #include <QTextToSpeech> namespace Ui { class Widget; }class Widget : publi…

JMeter 批量接口测试

一、背景 最近在进行某中台的接口测试准备&#xff0c;发现接口数量非常多&#xff0c;有6、70个&#xff0c;而且每个接口都有大量的参数并且需要进行各种参数验证来测试接口是否能够正确返回响应值。想了几种方案后&#xff0c;决定尝试使用JMeter的csv读取来实现批量的接口…

SFT会改善LLM性能,RLHF可能会损害性能

SFT&#xff08;Structured Fine-Tuning&#xff09;是一种模型优化技术&#xff0c;它通过在预训练的语言模型上进行有针对性的微调&#xff0c;以适应特定任务或领域。SFT可以提高性能的原因有几个&#xff1a; 领域自适应&#xff1a;预训练的语言模型通常在大规模通用语料库…

vscode 创建文件自动添加注释信息

随机记录 目录 1. 背景介绍 2. "Docstring Generator"扩展 2.1 安装 2.2 设置注释信息 3. 自动配置py 文件头注释 1. 背景介绍 在VS Code中&#xff0c;您可以使用扩展来为新创建的Python文件自动添加头部注释信息。有几个常用的扩展可以实现此功能&#xff0…

eChart显示时等比例缩放

eChart会在不同分辨率的显示器中显示&#xff0c;要求显示内容可以等比例缩放&#xff0c;transform的原点是内容的中心位置&#xff0c;直接使用transform.scale缩放会导致有些内容溢出屏幕 screen的左上角移动到屏幕的中心计算出比例&#xff0c;以screen左上角为原点&#…

leetcode-二进制求和

67. 二进制求和 class Solution:def addBinary(self, a: str, b: str) -> str:result carry 0for i in range(max(len(a), len(b))):a_bit a[-(i1)] if i < len(a) else 0b_bit b[-(i1)] if i < len(b) else 0sum_bit int(a_bit) int(b_bit) carryresult str…

Vue3:使用解构赋值来读取对象里的键-值对(值也是对象)

一、前言 在Vue3中&#xff0c;想要读取一个对象的“键—值”对&#xff08;值也是一个对象&#xff09;&#xff0c;数据格式如下&#xff1a; {1:{courseName: 课程1, study: 951526, visit: 3785553}&#xff0c;2:{courseName: 课程2, study: 181630, visit: 380830}&…