干货!!c++new和delete工作原理 以及 针对链表节点重载operator new 和operator delete 实现链表节点使用内存池申请和释放空间

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tonglin12138/article/details/85453825

第一部分: new和delete的实现原理

开始谈之前我们应该了解另一个概念“operator new”和“operator delete”:

new操作符调用一个函数来完毕必需的内存分配,你可以重写或重载这个函数来改变它的行为。new操作符为分配内存所调用函数的名字是operator new()。

函数operator new 通常这样声明:
void * operator new(size_t size);

返回值类型是void*,由于这个函数返回一个未经处理(raw)的指针。未初始化的内存。(假设你喜欢。你能写一种operator new函数,第二部分就是这样做的)。


注意点:

1.operator new是用来分配内存的函数,为new操作符调用。能够被重载.
2.你能添加额外的參数重载函数operator new,可是第一个參数类型必须是size_t。
  1. 内置类型
    如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。

  2. 自定义类型
    //new的原理
    第一步: 调用operator new函数申请空间
    第二部: 在申请的空间上执行构造函数,完成对象的构造

    //delete的原理
    第一步: 在空间上执行析构函数,完成对象中资源的清理工作
    第二步: 调用operator delete函数释放对象的空间

    //new T[N]的原理
    第一步:调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
    第二步:在申请的空间上执行N次构造函数
    //delete[]的原理
    第一步:在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
    第二步:调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

第二部分:针对链表节点重载operator new 和operator delete 实现链表节点使用内存池申请和释放空间

#include<memory>
#include<iostream>
using namespace std;

struct ListNode{
	ListNode* _prev;
	ListNode* _next;
	int _data;

	void* operator new(size_t size)
	{
		void *p = nullptr;
		p = allocator<ListNode>().allocate(10);
		cout << "memory  pool  create OK!!!"<<endl;
		return p;
	}

	void operator delete(void *p)
	{
		allocator<ListNode>().deallocate((ListNode*)p,10);
		cout << "memory pool be deallocated !!!" << endl;
	
	}

};



//带头的双向循环链表
class List
{
public:
	List()
 {
		
		//这块尤其容易出错;一定要用正确的,合适的指针去更新  

		_head = new ListNode;
		_head->_prev=_head;
		_head->_next=_head;

	}

	~List()
	{
		ListNode* cur = _head->_next;                 //_head->next指向首元结点
		while (cur != _head)
		{
			ListNode* next = cur->_next;
			delete cur;
			cur = next;
		
		}
		delete _head;
		_head = nullptr;
	
	}

private:
	ListNode* _head;

};

int main()
{
	List l1;
	l1.List::List();//类外调用成员函数需要加作用域
	l1.List::~List();   //程序会崩溃,原因是因为你显示的调用了List的析构函数,而程序退出时,又自动调用了一次
	system("pause");
	return 0;
}

通过调用发现我们这个时候如果针对ListNode节点使用new或者delete的时候,就会调用我们自己重载的operator new函数,输出相关的打印信息。

猜你喜欢

转载自blog.csdn.net/tonglin12138/article/details/85453825
今日推荐