植物大战 动态内存——C++

news2024/11/28 10:37:21

这里是目录标题

  • 前言
  • 动态内存分布
  • 如何理解C++语法的增加
  • new
    • new用法
  • 关于struct和class的使用
  • 关于free和delete的区别。
  • 背会这句话
  • 抛异常
  • operator new和operator delete
  • 内存池
  • new和delete原理
  • 定位new
  • malloc和new的区别是什么?
  • 内存泄漏

前言

总结复习前面的知识。

注意:学了C++在做oj题目时,不一定非要用类。
可以多项选择最简单的就行。怎么简单怎么写。

可以用类名定义一个匿名对象。
匿名对象的声明周期只在那一行。

weight();//匿名对象,匿名周期就是当前行。

假如构造+拷贝构造在一起运行,则编译器会优化步骤。

f(weight());//先构造匿名对象weight(),然后再传参拷贝构造。

结论:一个表达式中,连续步骤的构造+拷贝构造
或者拷贝构造+拷贝构造。胆大的编译器都会优化,合二为一。

动态内存分布

最上面是栈。然后是堆,静态区(系统叫做数据段),常量区(代码段)。这里的代码不是我们写的代码,而是那些指令。

栈和堆是程序运行起来才开辟空间的。

为什么要区分这些区域?
因为不同数据需要存在不同的位置。

int glob = 1;
static int staticglob = 1;
void test()
{
	static int staticvar = 1;
	int loacalvar = 1;
	int num1[10] = {1,2,3,4};
	char char2[] = "abcd";
	char* pchar3 = "abcd";
	int* ptr1 = (int*)malloc(sizeof(int)*4);
	int* ptr2 =(int*)calloc(4,sizeof(int));
	int* ptr3 = (int*)realloc(ptr2,sizeof(int)*4);
}

globalvar是全局变量,全局变量从语言的角度看在静态区。从系统看在数据段。

staticgob是静态变量,也在静态区。

staticvar是静态变量,在静态区

总结:全局变量和静态变量的声明周期都是全局的。所以都在静态区。

localvar是局部变量,局部变量是在栈上开辟的。

num1代表的是这个数组,数组是在栈上的。

char2在栈上。char2是一个数组,这个数组在栈上。他是用常量字符串abcd ** 拷贝 过去初始化他的。注意这个拷贝**。

*char2在也是在栈上。因为它代表的是这个数组指向的内容,内容也在栈上。

pchar3也在栈上

*pchar3解引用得到是常量区的字符串abcd所以在常量区。

ptr1在栈上。

*ptr1在堆上。因为他是malloc开辟的。

const修饰的叫做常变量,常变量是在栈上。

如何理解C++语法的增加

比如函数重载,引用,new/delete,流插入和流提取运算符。类和对象。

都是为了弥补C语言的不足。可能C++的发明者当时用C语言写

new

malloc和calloc的区别是什么呢?
malloc是开空间。
calloc是开空间+初始化。

realloc是扩容,有空间原地扩,无空间,异地扩。

C语言已经有了开空间的方法。C++为什么搞了一个new?

new和delete配合使用。
new是为了解决C语言中不好用的地方。

new用法

new是先开空间,再调用构造函数进行初始化。,
对于内置类型而言,用malloc和new除了用法不同,没有什么区别,他们的区别在于自定义类型。

//new 一个对象
int* p1 = new int;
//new 10个对象
int* p2 = new int[10];
//new一个对象初始化为10
int* p3 = new int(10);
//C++11的数组初始化
int* p4= new int[10]{10,1,2,3};

//初始化时一定要匹配释放。
delete p1;
delete[] p2;
delete p3;
delete[] p4;

对于自定义类型链表创建结点来说。

struct ListNode
{
	ListNode* next;
	int val;
	//构造函数
	ListNode(int val = 0)
		:_next(nullptr)
		,_val(val)
	{}
};


以下是C语言的用法,特别麻烦。
在这里插入图片描述
但是对于C++来说。C++直接用new就行,因为new会自动调用构造函数。假如构造函数写了就会自动初始化。

ListNode* n = new ListNode;

关于struct和class的使用

struct里面默认都是共有的,一般都要访问的设置为公有,比如list的节点ListNode。

class里面成员默认都是私有的。

关于free和delete的区别。

free直接把指向的当前指针释放。而不管指针的指针,容易导致内存泄漏。

而delete会进行以下两个步骤。

1.先调用析构函数,可以在释放析构函数里面的指针等资源,让空间进行释放。交还给操作系统。
2.再释放当前指针所指向的空间。

背会这句话

创建对象的时候会调用构造函数,假如没写,就是有默认构造函数。对于内置类型来说不做处理,对于自定义类型调用他的默认构造函数。

抛异常

1.对于C语言我们开辟空间失败需要检查,加上assert,malloc失败会返回空指针。

2.对于C++的new来说开辟空间失败会抛异常

怎么捕获异常?
异常的原理是根据继承和多态实现的。

例如以下代码就是抛异常
try和catch会二选一执行。抛异常就执行catch。

try
{	
	void* p2 = new char[124*1024*1024];
}
catch(const exception& e)
{
	cout << e.what() << endl;
}

那我们平常使用new都需要抛异常吗?
答案是不需要的。异常一般是在函数外面检查异常的。

operator new和operator delete

重点:new的底层原理是调用operator new和构造函数。

千万要注意。这个虽然带了operator这个词,但不是重载new

实际这个operator new封装了malloc,malloc失败抛异常。
operator封装了free。

这两个本质和malloc有什么区别吗?实际上没有区别。功能上一样,失败以后不抛异常。

开空间例子。

Stack* st = (Stack*)operator new(sizeof(Stack));
operator delete(st);

那operator new有什么用呢?
是为了new而设计的。
new会调用operator new和构造函数。!!
operator new的作用是调用malloc,假如malloc然后抛异常。假如成功则继续进行构造函数。

构造函数的作用是初始化。

内存池

假如我们频繁的向堆申请和释放空间,这时候可以用一个内存池,因为内存池更快,可以提高效率。

因为堆他中间需要调用operator new,operator new还需要再调用mallo成本很高。

而内存池里面的内存就可以直接用,效率很快。

C++的重载new就可以解决直接调用new而导致效率低下的问题。

就是把new进行重载。来调用内存池。
把delete进行重载,直接调用内存池。

new和delete原理

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

针对一个空间,显示调用构造函数进行初始化
例子

Stack* obj  = (Stack*)operator new(sizeof(Stack));
new(obj)Stack(4);

//相当于
Stack* obj = new Stack(4);

malloc和new的区别是什么?

怎么考虑这个问题呢?
1.从用法上的区别
2.从底层的区别
malloc和free是函数,new和delete是操作符。

底层上的区别就是new会调用构造函数。
free会调用析构函数。

内存泄漏

什么是内存泄漏?

内存泄漏的意思是指针丢了。 是将内存还给了操作系统。

内存泄漏真正的危害是什么?

普通的内存泄漏我们不用怕,就算我们不释放。正常的程序结束,内存就会还给操作系统。

怕的是什么?
怕的是我们的电脑内存很小,或者长期运行的程序,这时候用的时候需要delete。

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

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

相关文章

一文带你了解什么是云计算网络运维工程师,以及2023年的就业前景

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.云计算网络运维工程师是做什么的? 二.作为一名云计算网络运…

MyBatis(用于简化JDBC开发)

MyBatis是一款持久层框架&#xff0c;用于简化JDBC开发 持久层&#xff1a;将数据报错到数据库&#xff0c;持久化更改的意思 javaEE三层架构&#xff1a;表现层&#xff08;页面&#xff09;、业务层&#xff08;处理逻辑&#xff09;、持久层&#xff08;数据永久化更改&am…

拉伯证券|人心动了?刚刚,A股、港股大涨!

昨日A股传言较多&#xff0c;引发波动。上一年10月底11月初&#xff0c;也有类似情况。换个视点看&#xff0c;这说明人心开端动了&#xff0c;至于怎样个“思变”法&#xff0c;市场可能现已给出了答案&#xff01; 今天上午&#xff0c;A股大涨&#xff0c;北向资金净流入110…

cs231n-2022-01 Assignments1-numpy的使用

numpy的使用 Numpy是Python中科学计算的核心库。它提供了一个高性能的多维数组对象&#xff0c;以及处理这些数组的工具。如果你已经熟悉MATLAB&#xff0c;你可能会发现这个教程对开始使用Numpy很有用。 运行并阅读cs231n课程网站上提供的示例代码&#xff0c;感觉十分简洁&a…

TIA博途SCL学习_堆栈的入栈和出栈(后入先出)程序示例

TIA博途SCL学习_堆栈的入栈和出栈(后入先出)程序示例 如下图所示,添加一个FB块,语言选择SCL,命名为“入栈”, 如下图所示,通过FOR循环实现堆栈数组内的元素的移动,并将入栈的数据赋值给数组的第一个元素, 如下图所示,添加一个全局DB块,在该DB块中添加一个长度为10…

Visio中插入Mathtyp公式

Visio中插入Mathtype公式 打开visio软件&#xff0c;依次点击“插入”–“对象”–“mathtype 6.0 equation”–“确定”&#xff0c;也可以得到我们想要的公式。 点击“对象”&#xff0c;然后显示出Mathtype公式 点击“Mathtype 7.0”&#xff0c;然后显示公式框 Way 1&a…

win10和win11鼠标灵敏度修改和大小颜色其他等步骤

目录 一、前言 二、win10鼠标设置 1.进入鼠标设置界面 2.鼠标速度的调节 3.鼠标大小和颜色的调节 4.鼠标其他设置 三、win11鼠标设置 1.进入搜索界面 2.鼠标大小和颜色设置 3.鼠标的移动灵敏速度设置 4.鼠标图标的自定义 一、前言 在使用电脑鼠标时候&#xff0c;会觉…

【自然语言处理】【ChatGPT系列】WebGPT:基于人类反馈的浏览器辅助问答

WebGPT: 基于人类反馈的浏览器辅助问答《WebGPT: Browser-assisted question-answering with human feedback》论文地址&#xff1a;https://arxiv.org/pdf/2112.09332.pdf 相关博客 【自然语言处理】【ChatGPT系列】WebGPT&#xff1a;基于人类反馈的浏览器辅助问答 【自然语言…

[HTML] HTML基础知识

1.HTML简介 HTML指的是超文本标记语言(HyperText Markup Language)&#xff0c;是一种用于创建网页的标准标记语言 HTML页面基本结构 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X…

SpringMVC框架

一、什么是 SpringMVC ? SpringMVC框架是以请求为驱动&#xff0c;围绕Servlet设计&#xff0c;将请求发给控制器&#xff0c;然后通过模型对象&#xff0c;分派器来展示请求结果视图。其中核心类是DispatcherServlet&#xff0c;它是一个Servlet&#xff0c;顶层是实现的Ser…

不会指针?还不进来看看——进阶指针详解

专栏&#xff1a;C语言 每日一句&#xff1a;人贵有自知之明&#xff0c;知道什么可为和不可为。若不可为&#xff0c;怎样做才能可为&#xff0c;那何时可为。 进阶指针前言一、字符指针二、指针数组1.指针数组的介绍2.指针数组的使用三、数组指针1.数组指针的介绍2.&数组…

历史大讲堂:真那么好用?Windows前世今生

hello大家好&#xff0c;这里是每天日更哒博主。 还记得我第一次说的Microsoft Dos吗&#xff1f;那期我提到一次Windows并许诺要讲讲&#xff0c;这不来了&#xff01;今天我们就详细的盘一盘最好用的系统Windows真有那么神吗&#xff1f; 注意&#xff01;以下内容包含非常…

人脸识别美颜算法实战-深度学习基础知识

深度学习与机器学习的区别: 机器学习:人类定义输入数据的特征 深度学习:机器自动找到输入数据的特征 在深度学习中,采用多层的神经网络架构来提取图像 信息,越靠近底层的神经网络提取出来的都是点、线等低维度特征, 而高维度的神经网络层则会更多地保留比如耳朵、眼睛…

MySQL事务基础知识

前言 学习/导流&#xff1a; 小林coding - 事务篇 学习意义 理解MySQL如何去处理并发问题&#xff0c;借鉴其思想存储作为应用的关键能力&#xff0c;而事务作为关系型数据库的关键概念&#xff0c;掌握很必要&#xff0c;也为分布式事务学习做奠基 相关说明 该篇博文是个…

快速搭建springboot程序

SpringBoot快速入门 观狂神讲解视频笔记 【狂神说Java】SpringBoot最新教程IDEA版通俗易懂 第一个springboot程序 使用 idea 可以快速构建一个 springboot 的项目&#xff1a; 1.创建新项目&#xff0c;选择 spring initializr&#xff08;会默认通过官网快速构建&#xff09…

【编程经验】如何学习编程语言的秘诀,编程语言选择,按需学习

大家好&#xff0c;欢迎来到停止重构的频道。最近有些朋友问我们如何学习编程、初学软件的问题&#xff0c;我们打算出几期内容聊聊我们的建议。本期聊一下如何学习编程语言。我们将压箱底的诀窍介绍给新手朋友&#xff0c;当然这仅仅是我们的一些经验&#xff0c;并不是绝对的…

连续四年第一!

近日&#xff0c;IDC发布《2022 H1中国AI云服务市场研究报告》&#xff0c;百度智能云连续四年市场份额第一&#xff0c;整体占比28.1%&#xff0c;在"人体人脸"、"图像视频"‍两个规模最大的子市场继续保持第一。‍‍ 在图像视频等多个领域蝉联市场第一 …

PLC算法系列之数值积分器(Integrator)

数值积分和微分在工程上的重要意义不用多说,闭环控制的PID控制器就是积分和微分信号的应用。流量累加也会用到。有关积分运算在流量累加上的应用,请参看下面的文章链接: SMART S7-200PLC流量累计算法实现(梯形图算法详解+优化)_RXXW_Dor的博客-CSDN博客_smart 200 流量积分…

【bootstrap】使用,初学者的总结

官网&#xff1a;bootstrap中文网 首页点击v3文档&#xff0c;然后下载最左边的那个。 解压后把里面的css和js文件复制过去&#xff0c;因为也要用到jQuery&#xff0c;所以要把jQuery.min.js也一起放入js文件夹。 然后&#xff0c;就是导入&#xff1a; <link rel"s…

Java互联网支付系统源码,基于SpringBoot,含支付宝,微信,银联详细代码案例

spring-boot-pay 支付服务&#xff1a;支付宝&#xff0c;微信&#xff0c;银联详细 代码案例 (支付宝和微信支付测试均需要企业认证&#xff0c;如果没有企业推荐使用 [服务商模式] 申请开通个人商户 也可以测试 )&#xff0c;项目启动前请仔细阅读 注意事项 :fa-hand-o-left…