【编程】C++入门:operator new与operator delete函数、 new和delete的实现原理

operator new与operator delete函数

new和delete是用户进行动态内存申请和释放的操作符

  1. operator new和operator delete是系统提供的全局函数
  2. new在底层调用operator new全局函数来申请空间
  3. delete在底层调用operator delete全局函数来释放空间
  4. operator new和operator delete不是运算符重载函数
/*
operator new:该函数实际通过malloc来申请空间
*/
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
	// try to allocate size bytes
	void *p;
	// malloc函数在开辟失败后只是返回NULL指针
	// operator new函数 封装 malloc函数
	// 如果空间申请失败,进入while循环
	while ((p = malloc(size)) == 0)
		// 空间申请失败后的补救措施_callnewh()
		// 如果补救措施失败
		if (_callnewh(size) == 0)
 		{
			// report no memory
 			// 这里会抛出bad_alloc类型异常
 			static const std::bad_alloc nomem;
 			_RAISE(nomem);
 		}
 	return (p);
}

/*
operator delete: 该函数最终是通过free来释放空间的
*/
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;
}

/*
free的实现
*/
#define free(p) _free_dbg(p, _NORMAL_BLOCK)

通过底层全局函数的实现知道:

  1. operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛出异常。
  2. operator delete 最终是通过free来释放空间的。

operator new与operator delete的类专属重载

针对链表的节点ListNode,通过重载类专属 operator new/operator delete实现链表节点使用内存池申请和释放内存,不需要频繁的申请/释放内存,提高代码效率。

定位new表达式(placement-new)

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

使用场景:
定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显式调构造函数进行初始化。

class Date
{
public:
	Date()
		: _year(1)
		, _month(1)
		, _day(1)
	{}

	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	// ptr现在指向的只不过是与Date对象相同大小的一段空间
	// 还不能算是一个对象,因为没有执行-构造函数-
	Date* ptr = (Date*)malloc(sizeof(Date));
	// 定位new表达式
	new(ptr) Date;	// 无参构造函数
	new(ptr) Date(2021, 2, 13);	// 有参构造函数

	return 0;
}

你可能感兴趣的:(【编程】C++入门:operator new与operator delete函数、 new和delete的实现原理)