类和对象(4)

news2024/10/5 19:12:33

文章目录

  • 1. C/C++内存分布
  • 2. C语言中动态内存管理方式:malloc/calloc/realloc/free
  • 3.C++内存管理方式new/delete
    • 3.1 new/delete操作内置类型
    • 3.2 new/delete操作自定义类型
  • 4. operator new和operator delete函数(重点)
    • 4.1底层原理
  • 5.malloc/free和new/delete的区别
  • 6. 定位new表达式(placement-new)

1. C/C++内存分布

int globalvar = 1;
static int staticGlobalvar = 1;
void Test()
{
	static int staticVar = 1;
	int localvar = 1;

	int num[10] = { 1,2,3,4 };
	char char2[] = "abcd";
	const char* pChar3 = "abcd";
	int* ptr1 = (int*)malloc(sizeof(int) * 4);
	int* ptr2 = (int*)malloc(4, sizeof(int));
	int* ptr3 = (int*)relloc(ptr2, sizeof(int) * 4);
	free(ptr1);
	free(ptr3);
}
  • 选项:A. 栈 B.堆 C.数据段(静态区) D.代码段(常量区)
  • globalvar:____ - staticGlobalar:_____ -staticVar:______
  • localVar:_____ - num1:____
  • char2:_____ - *char2:_____
  • pChar3:____ - *pChar3:____
  • ptr1:____ - *ptr1:_____
    C C C A A A A A D A B
  • sizeof(num1)=____ - sizeof(char2)=____ - strlen(char2)=______
  • sizeof(pChar3)=____ - strlen(pChar3)=____ - sizeof(ptr1)=______
    40; 5; 4(遇见\0截止); 4/8(是一个指针,和后面指向的东西没有关系,32位4,64位8); 4(有效字符的个数); 4/8(指针)
    在这里插入图片描述
  1. 又叫堆栈–非静态局部变量/函数参数/返回值等,栈是向下增长的
  2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可以使用系统接口创建共享共享内存,做进程间通信
  3. :用于程序运行时的动态内存分配,堆可以是向上增长的。
  4. 数据段:存储全局数据静态数据
  5. 代码段:可执行的代码/只读常量

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

void Test()
{
	int* p1 = (int*)malloc(size(int));
	free(p1);

	//1.malloc/calloc/realloc的区别?
	int* p2 = (int*)calloc(4, sizeof(int));
	int* p3 = (int*)realloc(p2, sizeof(int) * 10);

	//这里需要free(p2)嘛?
	free(p3);
}

3.C++内存管理方式new/delete

不推荐malloc和free,C++的new/delete更简洁,对内置类型差别不大,自定义类型会调用构造函数和析构函数。

3.1 new/delete操作内置类型

int main()
{
	int* p1 = new int;//new不用检查,不会初始化。
	int* p2 = (int*)malloc(sizeof(int));//要去强转,VS2019检查严格
	if (p2 == nullptr)
	{
		perror("malloc fail");
	}
	return 0;
}
int* p3=new int(0);//初始化为0
delete p3;
int* p4=new int[10];//申请了10个int的数组
delete[] p4;
int* p5=new int[10]{1,2,3,4};//初始化

new可以帮助初始化

void Test()
{
	//动态申请一个int类型空间
	int* ptr4 = new int;

	//动态申请一个int类型的空间并初始化为10
	int* ptr5 = new int(10);

	//动态申请10个int类型的空间
	int* ptr6 = new int[3];
	delete ptr4;
	delete ptr5;
	delete[] ptr6;
}

new一定要去匹配使用,不要交叉,否则结果不确定。

3.2 new/delete操作自定义类型

单个对象调单次构造函数,多个对象调多次构造函数。delete调析构函数
根本上而言,C和C++内存管理用一套模式

4. operator new和operator delete函数(重点)

4.1底层原理

库里面的全局函数operator new和operator delete,不是运算符重载。本质是malloc和free的封装。
new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是全局函数。new在底层调用delete new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间

int main()
{
	//出错机制不同
	//失败以后抛异常
	int* p1=(int*)operator new(sizeof(int*));
	//失败返回空nullptr
	int* p2 = (int*)malloc(sizeof(int*));
	if (p2 == nullptr)
	{
		perror("malloc fail");
	}

	//面向对象的语言处理错误时基本上使用抛异常。
	//new 1.申请空间 operator new,封装malloc 2.调用构造函数
	A* p3 = new A;//调用operator new
	
	//delete需先调用析构函数,在使用p3指向的空间
	delete p3;
	
    //申请空间 operator new[]->operator new->封装malloc
    //调用10次构造函数
	A* p6 = new A[10];
	delete[] p6;
    //delete需先调用10次析构函数,在使用operator delete[] p6指向的空间

    int* p7 = new int[10];
	free(p7);
	//不会造成内存泄露,因为针对的是内置类型,不会报错
	A* p8 = new A;
	free(p8);
	//不会报错。operator delete->free,只是没有调用析构函数,少调不会报错
	
	return 0;
}
class Stack
{
public:
	Stack()
	{
		cout << "Stack()" << endl;
		_a = new int[4];
		_top = 0;
		_capacity = 4;
	}
private:
	int* _a;
	int _top;
	int _capacity;
};
Stack st;
//调用构造,会调用析构

Stack* pst = new Stack;//指针,内置类型,不调用析构
//pst:4个字节,是个指针。new的机制:开空间,12个字节,开在堆上面,再调用构造函数,再去堆上开16个字节,也就是4个整型
delete pst;

在这里插入图片描述

  1. 先调用析构函数,完成栈指向的资源的清理
  2. 调用operator delete(pst),释放结构对象的空间。
  3. 由于底层的实现有关联交叉,不匹配使用可能有问题可能没有问题,因此最好要匹配使用
A* p9=new A[10];
free(p9);//报错
delete p9;//报错
delete[] p9;//没有问题

了解其底层机制

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

  • 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在释放空间前会调用析构函数完成空间中资源的清理。
    用法+底层原理
int main()
{
	size_t size = 0;
	while (1)
	{
		int* p1 = (int*)malloc(1024 * 1024 * 4);

		if (p1 == nullptr)
		{
			break;
		}
		size += 1024 *1024* 4;
		cout << p1 << endl;
	
}
	cout << size << endl;
	cout << size/1024/1024 << "MB"<<endl;

}

C++出错抛异常。

在这里插入图片描述

int main()
{
	size_t size = 0;
	try
	{
		while (1)
		{
			int* p1 = new int[1024 * 1024];

				if (p1 == nullptr)
				{
					break;
				}
			size += 1024 * 1024 * 4;
			cout << p1 << endl;

		}
	}
	catch (const exception& e)
	{
		cout << e.what()<< endl;
	}
	
	cout << size << endl;
	cout << size/1024/1024 << "MB"<<endl;

}

在这里插入图片描述
bad allocation:申请内存失败。

6. 定位new表达式(placement-new)

定位new表达式是在一分配的原始内存空间中调用构造函数初始化一个对象
使用格式:
new(place_address)type或者new(place_address)type(initializer-list)
place_address必须是一个指针,initializer-list是类型的初始化列表

int main()
{
	A aa;
	A* p1 = (A*)malloc(sizeof(A));
	if (p1 == nullptr)
	{
		perror("malloc fail");
	}//构造函数不能显式调用
	//对一块已有的空间初始化——定位new
	//new(p1)A;
	//定位new
	new(p1)A(1);//需要有参数
    //调用析构函数:
	p1->~A();
	free(p1);
	return 0;
}

//改进malloc
A* p2 = new A;
delete p2;

有一类场景需要这个malloc,需要提升性能,内存从内存池进行申请
在这里插入图片描述

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

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

相关文章

24届双非本科找工作到底有多难

记录一下自己的找工作过程&#xff0c;今天笔试失败感觉整个人都颓废了(那家公司真的是我的目标情司&#xff0c;呜呜呜&#xff0c;感觉我是废物)。 再加上不考虑出省&#xff0c;感觉找工作太难了 介绍一下自己情况&#xff1a;三个省奖&#xff08;开发类的&#xff0c;负责…

性能测试模型-业务模型、策略模型、数据模型

针对性能测试具体方案的设计进行抽象和总结,将其归纳为6个性能测试模型。 业务模型 业务模型是一组功能点或接口的集合及其占比情况,用于合理地模拟生产上真实的业务发生场景 在实施范围上,业务模型为本项目明确实施范围,梳理涉及的业务系统及其完整链路等 在实施结果价值…

提示词加神秘咒语让大模型更加聪明

谷歌团队研究发现&#xff0c;提示词加上神秘咒语深呼吸(take a deep breath&#xff09;结合大家已经熟悉的“一步一步地想”&#xff08;Let’s think step by step&#xff09;&#xff0c;大模型在数据集上的成绩就提升了12%。而且这个最有效的提示词&#xff0c;是AI自己找…

bug总结问题集和知识点集(一)

目录 一 bug问题集1. 端口被占用 二 oracle1. oracle查看版本怎么操作2. oracle数据库&#xff1a;参数个数无效![在这里插入图片描述](https://img-blog.csdnimg.cn/6a2eebc164f9406c81525371893bbd11.png)3. ORACLE数据库如何完整卸载? 三 mybatis1. mybatis用注解如何实现模…

算法|图论 6 并查集

并查集基本模板&#xff1a; int n 10; vector UFSets(n,0);//若将初值全设置为-1&#xff0c;那就不用再有初始化操作了。//初始化 void Initial(vector<int> S[]){for(int i0;i<n;i){S[i] -1;} }//查操作 int Find(vector<int> &S,int x){int root x;…

【红包雨压测环境】

文章目录 红包雨压测环境并发预估积分与权重对于新用户&#xff0c;活跃度占比为70%&#xff0c;贡献度占比为30%。活跃度权重分配&#xff1a;贡献度权重分配&#xff1a; 对于高质量作品的作者&#xff0c;活跃度占比为30%&#xff0c;贡献度占比为70%。活跃度指标权重&#…

杭州企业型通配符SSL数字证书

通配符SSL数字证书是众多数字证书产品中比较特殊的一款产品&#xff0c;在互联网安全领域&#xff0c;SSL数字证书是保障网站安全性的一种重要手段。而通配符SSL数字证书&#xff0c;更是其中的一种特殊类型&#xff0c;它允许用户对多个域名进行保护&#xff0c;只需一张证书即…

C++--简单实现定长内存池

1.什么是定长内存池 在C/C中&#xff0c;动态申请内存都是通过malloc来申请的&#xff0c;但是实际上不是是直接从堆上直接申请的内存&#xff0c;而是通过malloc动态申请一大块内存&#xff0c;malloc就相当于一块内存池&#xff0c;然后分给程序使用&#xff0c;如果申请的内…

网络安全进阶学习第十六课——业务逻辑漏洞介绍

文章目录 一、什么是业务逻辑二、业务逻辑漏洞的成因三、逻辑漏洞的重要性四、业务逻辑漏洞分类五、业务逻辑漏洞——业务授权安全1、未授权访问2、越权访问1) 平行越权&#xff08;水平越权是指相同权限的不同用户可以互相访问&#xff09;2) 垂直越权&#xff08;垂直越权是指…

企业架构LNMP学习笔记47

企业架构队列缓存中间件分布式redis&#xff1a; 一直想学习下这块的。今天总算学到了&#xff0c;好好把redis的这块内容理解下。 1&#xff09;能够描述Redis作用及其业务适用场景 &#xff1b; 2&#xff09;能够安装配置启动Redis&#xff1b; 3&#xff09;能够使用命令…

Qt使用注意事项

1.菜单选项不能出现数字&#xff0c;可以是 英文 加 “_”&#xff1a; 2.如何确保加载的图片&#xff0c;尺寸大小与原来一样&#xff1f; 【QT】添加图片资源并使用QImage加载图片显示_qimage显示图片_李春港的博客-CSDN博客 ui->PicLabel->setPixmap(QPixmap::fromIm…

(9.8-9.14)【大数据新闻速递】

加gzh“大数据食铁兽”&#xff0c;了解更多大数据快讯 【2023百度十大科技前沿发明】 近日&#xff0c;百度发布了“2023百度十大科技前沿发明”&#xff0c;包括“基于大模型的检索生成决策交互一体的智能系统”“基于大模型的端到端搜索技术”“飞桨端到端自适应的分布式训…

网络工程师的甩锅指南,果断收藏

大家好&#xff0c;我是老杨。 都说IT行业最容易被甩锅的就是网工&#xff0c;这是有科学依据的&#xff0c;比如&#xff1a; 纵观我网工群的群友聊天&#xff0c;“锅”不离口&#xff0c;很难不说明一点什么问题。 遇到甩锅&#xff0c;我相信没有哪位朋友的心情是愉悦的。…

父子工程搭建

1. 构建父工程 父工程的职责是对依赖包的版本进行管理&#xff0c;创建父工程分两步&#xff0c;第一创建父工程&#xff0c;第二在pom.xml编辑依赖管理。 进入新建模块界面&#xff0c;选择Spring Initializr&#xff0c;填写模块的信息&#xff1a; 创建成功&#xff0c;删…

linux服务器内服务访问域名Name or service not know

目录 linux服务器内服务访问域名Name or service not know 1.前言2.排查是不是这个域名无法访问2.1服务内ping 这个域名2.2在浏览器打开这个域名2.3服务内ping 这个域名所对应的ip2.4在服务器内配置host 总结参考 文章所属专区 项目问题解决 1.前言 linux服务器内服务访问域名…

许可分析 license分析 第五章

许可分析是指对软件许可证进行详细的分析和评估&#xff0c;以了解组织内部对软件许可的需求和使用情况。通过许可分析&#xff0c;可以帮助组织更好地管理和优化软件许可证的使用。以下是一些可能的许可分析方法和步骤&#xff1a; 软件许可证自动化管理&#xff1a;考虑使用自…

飞驰的高铁-第15届蓝桥杯第一次STEMA测评Scratch真题精选

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第150讲。 飞驰的高铁&#xff0c;本题是2023年8月20日举行的第15届蓝桥杯STEMA测评Scratch编程中级组编程第2题&#…

字节、京东等大厂年薪50w的测试都什么水平?

各位做测试的朋友&#xff0c;但凡经历过几次面试&#xff0c;那么你一定曾被问到过以下问题&#xff1a; 1、在Linux环境下&#xff0c;怎么执行web自动化测试&#xff1f; 2、Shell如何&#xff0c;Docker熟悉吗&#xff1f; 3、全链路的压测实操过吗&#xff0c;如何推进与开…

hexo搭建一个自己的博客

hexo腾讯云服务器搭建一个自己的博客 我的博客: http://www.elcarimqaq.top/ 前期准备 node.js&#xff1a; https://nodejs.org/en/ git&#xff1a;https://git-scm.com/download/win hexo官方文档&#xff1a;https://hexo.io/zh-cn/docs/index.html 安装hexo npm ins…

“存量竞争” 体验为王,火山引擎边缘云助力内容社区破局

今年4月&#xff0c;在宣布要技术升级、数据重构后&#xff0c;承载无数人青春的天涯社区疑似关停&#xff0c;一代传奇的衰落为所有内容社区释放出了不可忽视的信号。 图片来源&#xff1a;天涯官博 回顾天涯社区发展史&#xff0c;从“周公子大战易烨卿”、天涯十大诡异事件&…