首页 > 其他分享 >new与delete原理剖析

new与delete原理剖析

时间:2024-12-15 21:56:47浏览次数:6  
标签:函数 申请 剖析 operator 空间 new delete

一、operator newoperator delete函数

        C++除了提供【new】和【delete】关键字来进行动态内存管理,还提供了【operator new】与【operator delete】函数来进行动态内存管理

        【new】和【delete】是用户进行动态内存申请和释放的操作符,【operator new】和【operator delete】是系统提供的全局函数

        【new】在底层调用【operator new】全局函数来申请空间,【delete】在底层通过【operator delete】全局函数来释放空间

        1、 operator new

【operator new】:

        该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试执行空 间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常 

        C++系统库中的【operator new】实现:

void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
	// try to allocate size bytes
	void* p;
	while ((p = malloc(size)) == 0)
		if (_callnewh(size) == 0)
		{
			// report no memory
			// 如果申请内存失败了,这里会抛出bad_alloc 类型异常
			static const std::bad_alloc nomem;
			_RAISE(nomem);
		}
		return (p);
}

         可以观察到【operator new】的返回值是【void *】类型的,【size】为申请的空间大小,而该函数的核心就是使用【malloc】申请空间,如果【malloc】申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常

         2、operator delete

【operator delete】: 

        该函数最终是通过free来释放空间的

        C++系统库中的【operator delete】实现: 

void operator delete(void* pUserData)
{
	_CrtMemBlockHeader* pHead;
	RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
	if (pUserData == NULL)
		return;

	_mlock(_HEAP_LOCK); /* block other threads */
	__TRY

		/* get a pointer to memory block header */
		pHead = pHdr(pUserData);

		/* verify block type */
		_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

		_free_dbg(pUserData, pHead->nBlockUse);
	__FINALLY
		_munlock(_HEAP_LOCK); /* release other threads */
	__END_TRY_FINALLY

	return;
}
#define free(p) _free_dbg(p, _NORMAL_BLOCK)

        3、小结 

        【operator new】和【operator delete】有很多代码都看不懂,但是没有关系,我们只需要得到一个结论:

  • 【operator new】是【malloc】的封装,【operator delete】是【free】的封装 
  • 【operator new】与【operator delete】用法和【malloc】与【free】的用法是一样的

        示例: 

int main()
{
	int* num = (int*)operator new(sizeof(int));
	*num = 100;
	cout << *num << endl;
	operator delete(num);
}

         结果:

二、new与delete原理 

        1、内置类型

new的原理:
  1. 调用【operator new】函数申请空间
delete的原理:
  1. 调用【operator delete】函数释放对象的空间
如果申请的是内置类型的空间,【new】和【malloc】,【delete】和【free】基本类似,不同的地方是:
  • 【new】/【delete】申请和释放的是单个元素的空间,【new [ ]】和【delete [ ]】申请的是连续空间,而且【new】在申请空间失败时会抛异常,【malloc】会返回NULL

        2、自定义类型 

new的原理:
  1. 调用【operator new】函数申请空间
  2. 在申请的空间上执行构造函数,完成对象的构造
delete的原理:
  1. 在空间上执行析构函数,完成对象中资源的清理工作
  2. 调用【operator delete】函数释放对象的空间

        示例:

class Test
{
public:
	Test(int n = 100)
		:num(n)
	{
		cout << "构造函数" << endl;
	}
	~Test()
	{
		cout << "析构函数" << endl;
	}
private:
	int num;
};
int main()
{
	//原理:operator new + 构造函数
	Test* t = new Test;

	//原理:operator delete + 析构函数
	delete t;
	return 0;
}

        【new】底层运行逻辑:

        【delete】底层运行逻辑: 

        对于【new】和【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】来释放空间

        示例:

int main()
{
	//原理:operator new [ ] + 构造函数
	Test* t = new Test[10];

	//原理:operator delete [ ] + 析构函数
	delete[] t;
	return 0;
}

        【new】底层运行逻辑:

        值得注意的是这里调用的【operator new [ ] 】 函数,但是【operator new [ ] 】 函数其实就是【operator new】

        【operator new [ ] 】函数的底层实现:

void* __CRTDECL operator new[](size_t const size)
{
    return operator new(size);
}

        【delete】底层运行逻辑:  

        【delete】这边也是一样的,虽然调用的是【operator delete [ ] 】 函数,但是【operator delete [ ] 】 函数其实就是【operator delete】

        【operator delete [ ] 】函数的底层实现: 

_CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete[](void* const block, size_t const) noexcept
{
    operator delete[](block);
}

【注意】

        如果使用【new】时带方括号,则使用【delete】时也因该带方括号。如果使用【new】时不带方括号,则使用【delete】时也因该不带方括号。它们之间要匹配使用

        【new】与【delete】的格式不匹配导致后果是不确定的,因此我们不能依赖于某种特定的行为 

标签:函数,申请,剖析,operator,空间,new,delete
From: https://blog.csdn.net/LVZHUO_2022/article/details/144224178

相关文章

  • 深度剖析规划执行困境:基于单项任务优化的算法与策略探讨
    ......
  • 转载:【AI系统】NVLink 原理剖析
    随着AI技术的飞速发展,大模型的参数量已经从亿级跃升至万亿级,这一变化不仅标志着AI的显著提升,也对支持这些庞大模型训练的底层硬件和网络架构提出了前所未有的挑战。为了有效地训练这些复杂的模型,需要依赖于大规模的GPU服务器集群,它们通过高速网络相互连接,以便进行快速、高效......
  • 转载:【AI系统】Tensor Core 深度剖析
    TensorCore是用于加速深度学习计算的关键技术,其主要功能是执行神经网络中的矩阵乘法和卷积运算。通过利用混合精度计算和张量核心操作,TensorCore能够在较短的时间内完成大量矩阵运算,从而显著加快神经网络模型的训练和推断过程。具体来说,TensorCore采用半精度(FP16)作为输入......
  • 转载:【AI系统】NVLink 原理剖析
    随着AI技术的飞速发展,大模型的参数量已经从亿级跃升至万亿级,这一变化不仅标志着AI的显著提升,也对支持这些庞大模型训练的底层硬件和网络架构提出了前所未有的挑战。为了有效地训练这些复杂的模型,需要依赖于大规模的GPU服务器集群,它们通过高速网络相互连接,以便进行快速、高效......
  • 浮动许可证的优势剖析及其在许可证优化中的重要价值!
    1.引言随着信息技术的快速发展,软件已经成为企业运营不可或缺的一部分。为了有效地管理这些软件资源,浮动许可证作为一种灵活且高效的许可模式逐渐受到青睐。本文旨在深入探讨浮动许可证的优势,并分析如何通过优化实现更大的价值,特别是借助smartlic软件资产管理系统工具。2......
  • GPT-5 训练遇阻:预期目标难达成与交付延期的深度剖析
    #GPT-5训练遇阻:预期目标难达成与交付延期的深度剖析近期,GPT-5的训练进展引发了广泛关注与诸多讨论,令人遗憾的是,其训练并未达到预期目标,且难以在规定时间内交付。这一状况不仅让期待它的人们大感意外,也在人工智能技术领域掀起了不小的波澜。在训练过程中,数据处理环节遭遇了重......
  • 【语法】内置方法 __new__ 、 __init__、__call__
    在Python中,__new__、__init__ 和 __call__ 是三个特殊的方法,它们分别在不同的场景中被调用,并扮演着不同的角色。__new__ 方法__new__ 是一个静态方法,它在类实例化时首先被调用。它的主要职责是创建类的实例。在Python中,__new__ 是唯一一个可以覆盖对象实例化过程的方法......
  • 【有啥问啥】大语言模型Prompt中的“System指令”:深入剖析与误区澄清
    大语言模型Prompt中的“System指令”:深入剖析与误区澄清引言在与大语言模型(LLM)交互时,“prompt”(提示符)这一概念已不再陌生。Prompt是引导模型生成特定类型文本的关键输入,决定了模型的输出方向与质量。然而,随着大语言模型的广泛应用,出现了一些关于“system指令”的误解,特......
  • 深度剖析 ToF 技术:原理、优劣、数据纠错与工业应用全解析
    1 引言飞行时间(Time-of-Flight,简称ToF)技术是一种先进的三维成像技术,其工作机制与三维激光扫描技术有着相似之处。ToF技术的主要优势在于其能够一次性捕获整个场景的深度信息,而不是通过逐点扫描的方式来获取,这使得它特别适合于动态环境的三维成像。ToF相机通过捕捉光脉冲的......
  • RocksDB 内存超限问题剖析
    作者:来自vivo互联网服务器团队-ZengLuobin在使用RocksDB存储引擎的过程中,有部分开发者遇到了内存使用超出预期的情况。本文针对这一问题展开了深入分析,从内存使用原理、RocksDB内存管理机制、常见内存使用问题等方面进行了详细探讨,并提出了相应的解决方案和优化建议,希望......