‍第三章C/C++内存管理与模板(malloc)

‍Chapter 3 C/C++ Video Memory Management and Templates‍前言:

视频内存管理是 C++ 中最具争议的问题之一。显存管理在 C++ 中无处不在,几乎每个 C++ 程序都会发生显存泄漏。因此,如果你想成为 C++ 高级,显存管理是必须的。需要。

文章目录

一、C/C++ 中的程序区定义

了解动态图形在 C/C++ 中的工作原理对于成为合格的 C/C++ 程序员至关重要。 C/C++程序中的显存分为六个部分:

⭐描述

栈也叫栈——非静态局部变量/局部变量/函数参数/返回值等。栈是上下的,通常有指定的大小。 Linux栈是一个8M的显存映射段,是一种高效的I/O映射方式,用来加载一个共享的动态内存库。用户可以使用系统套接字来创建共享的共享视频内存,用于进程间通信。堆用于程序运行时动态分配内存,堆可以上下。堆比较大,通常有一个接近2G左右的空间数据段——存储全局数据和静态数据。代码段——可执行代码/只读常量(“helloworrld”)。 二、C语言中的动态内存管理方法

malloc/calloc/realloc/free

功能说明

void*malloc(intnum);

在堆区分配一块指定大小的显存空间来存储数据。这个内存空间在函数执行后不会被初始化,它们的值是未知的。

void*calloc(intnum,intsize);

在显存中动态分配num个size size的连续空间,并将每个字节初始化为0。相当于malloc+memset

void*realloc(void*address,intnewsize);

此函数重新分配显存并将显存扩展为newsize。如果空间足够,就在原地展开,如果空间不够,就在其他地方展开

voidfree(void*address);

该函数释放address指向的显存块,即动态分配的显存空间。

三、C++显存管理方法

C语言显存管理方法在C++中可以继续使用,但是有些地方力不从心,使用起来比较麻烦c语言中内存的申请和释放,所以C++提出了自己的显存管理方法:通过动态显存管理new 和 delete 运算符。

1.新建/删除操作外部类型

对于外部类型,new/delete 和 malloc/free 没有区别,只是语法不同。

	int* p1 = (int*)malloc(sizeof(int));
	// 动态申请一个int类型的空间
	int* p2 = new int;
	
	int* p3 = new int[5];// 动态申请5个int类型的空间
	int* p4 = new int(10);	// 动态申请一个int类型的空间并初始化为10
	
	int* p5= new int[5]{1,2,3};// C++11支持new[]用{}初始化,c++98不支持
	free(p1);
	delete p2;   //new/delete,new[]/delete[]一定要匹配,否则可能会出错
	delete[] p3;
	delete p4;
	delete[] p5;

应用和释放单个元素的空间,使用new和delete运算符,应用和释放连续空间,使用new[]和delete[],注意:匹配使用。

2.新建/删除操作自定义类型

new/delete 和 malloc/free 申请自定义类型的空间时,最大的区别是 new/delete 会调用构造函数和析构函数,不仅为自定义类型打开空间,new/delete 的目的是为自定义类型。

	//1、堆上申请空间 2、调用析构函数初始化
	A* p1 = new A;
	A* p2 = new A(10);
	A* p3 = new A[2];
	//1、调用析构函数清理对象中资源 2、释放空间
	delete p1;
	delete p2;
	delete[]p3;

总结:

1、在C++中,如果申请外部类型对象或链表,malloc和new没有区别

2、如果是自定义类型,差别很大,ne​​w是开空间+初始化,delete是销毁清除+释放空间,malloc和free只是开空间+释放空间

3、建议在C++中,无论是外部类型的应用发布还是自定义类型,都尽量使用new和delete。

4、新的失败不需要检查返回值,它会抛出异常。

3.malloc/free和new/delete的异同

共同点是,它们都是从堆中申请空间,需要用户自动释放。

区别在于:

malloc 和 free 是函数,new 和 delete 是运算符。 malloc申请的空间不会被初始化,但是new可以初始化。 malloc在申请空间的时候,需要自动估计空间的大小并进行转移。新建只需要跟随空间的类型。如果有多个对象,[]可以手动指定对象的数量。 malloc的返回值为void*,使用时必须转换,不需要new,因为new后面是空格的类型。 malloc申请空间失败时返回NULL,所以使用时必须为空,new不需要,但是new需要捕获异常。申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数和析构函数,而new申请空间后会调用构造函数完成对象的初始化,delete会调用释放空间之前的析构函数。完成空间内资源的清理。 4.哪些是显存泄漏以及显存泄漏的危害

什么是显存泄漏:显存泄漏是指遗漏或错误导致程序无法释放不再使用的显存的情况。显存泄漏并不是说显存在数学上消失了,而是应用程序分配了一定的显存后,由于设计错误,失去了对显存的控制,丢了针,从而造成了显存的浪费记忆。

显存泄漏的危害:显存泄漏发生在常年运行的程序中,如操作系统、后台服务等,显存泄漏会导致响应越来越慢,并最终陷入困境。

四、new 和 delete 运算符1.operatornew 和 operatordelete 函数

new和delete是供用户申请和释放动态显存的运算符。 Operatornew 和 operatordelete 是系统提供的全局函数。 new调用底层operatornew全局函数申请空间,delete使用底层operatordelete全局函数释放空间。

⭐operatornew 实际上是通过 malloc 申请空间的。如果malloc申请空间成功,则直接返回。否则,将执行用户提供的空间不足的响应。如果用户提供了这个动作,应用程序将继续,否则将抛出异常。封装了malloc,失败时抛出异常,符合C++封装和抛出异常的机制。 operatordelete 最终通过 free 释放空间。

注意:一般情况下,不需要重载operatornew和operatordelete,除非在申请和释放空间时有个别特殊要求。比如在使用new和delete申请和释放空间的时候,复制一些日志信息,可以简单的帮助用户检查是否有显存泄露。

2.new和delete的实现原理

外部类型:

如果申请外部类型的空间,new和mallocc语言中内存的申请和释放,delete和free基本类似,区别在于:new/delete为单个元素申请和释放空间,new[]和delete[]申请的是一个连续的空间,但是当new申请空间失败时,会抛出异常,malloc会返回NULL。

自定义类型:

new原理1.调用operatornew函数申请空间。 2.在申请的空间上执行构造函数,完成对象的构造。

删除原理

1.在空间上执行析构函数,完成对象内资源的清理。 2.调用operatordelete函数释放对象空间。

newT[N]的原理

1.调用operatornew[]函数,实际调用operatornew[]中的operatornew函数,完成N个对象空间的应用。 2.在请求的空间上执行构造函数N次。

delete[]的原理

1. 在释放的对象空间上执行N个析构函数,完成N个对象中资源的清理。 2.调用operatordelete[]释放空间,实际上调用operatordelete[]中的operatordelete释放空间。

3.定位新表达式(placement-new)

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

使用格式:

new(place_address)type 或 new(place_address)type(initializer-list)

place_address 必须是指针,initializer-list 是该类型的初始化列表

使用场景:

定位新表达式在实践中通常与显存池配合使用。由于显存池分配的显存没有初始化,如果是自定义类型的对象,需要使用new的定义表达式显示构造函数进行初始化。

	A* p = (A*)operator new(sizeof(A));//p现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行
	new(p)A(10);  //显示调用构造函数初始化这块空间
	p->~A();  //显示调用析构函数
	operator delete(p);

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 网站程序 ‍第三章C/C++内存管理与模板(malloc) https://www.wkzy.net/game/8505.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务