C++内存管理(未完...)

安稳与你 提交于 2019-12-17 23:24:01

本文代码中出现的类 

class Complex{
	public:
		int num;
		Complex(int _num) : num(_num){}
		Complex(){}
		~Complex(){}
};

 

四种常用内存申请方式 


	//--------四种内存申请方式----------
	void* p1 = malloc(512);          //申请512bytes
	free(p1);
	
	string* p2 = new string;         //申请one object
	delete p2;
	
	void* p3 = ::operator new(512);  //申请512bytes
	::operator delete(p3);
	
	
	int* p4 = allocator<int>().allocate(5); //分配5个int
	//int* p4 = allocator<int>().allocate(5, (int*)0); //同上,但是(int*)0并没有必要
	allocator<int>().deallocate(p4, 5);

new、delete的解析


	//---------------new的解析---------------------
	//Complex* cp = new Complex();
	
	//new的实现过程 
	Complex* cp;
	try{
		void* men = operator new(sizeof(Complex));
		cp = static_cast<Complex*>(men);
		//编译器执行为 cp->Complex::Complex(5); 但是我们只能写作如下: 
		new(cp)Complex(5);
	}catch(std::bad_alloc){
		
	}
	cout << cp->num << endl;
	
	//-----------delete的解析--------------------
	//delete cp;
	cp->~Complex();
	operator delete(cp);        //free(cp); 

 Array new


	//-----------Array new--------------
	Complex* cp = new Complex[7];
	//----------Array delete------------
	delete[] cp;

 初始化Arry

class A{
	public:
		int id;
		A() : id(0){ cout << "default ctor.this=" << this << "  id=" << id << endl; }
		A(int i) : id(i){ cout << "ctor.this=" << this << "  id=" << id << endl; }
		~A(){ cout << "ctor.this=" << this << "  id=" << id << endl; }
}; 

 

//-----------初始化一个array----------------- 
	const int size = 3;
	A* buf = new A[size];
	A* temp = buf;
	cout << "buf = " << buf <<" temp = " << temp << endl;
	
	for(int i  = 0; i < size; i++ ){
		new(temp++)A(i);
	}
	
	cout << "buf = " << buf << " temp = " << temp << endl;
	
	delete[] buf;

 基本数据类型的Array new

//-------------------int类型的array new------------------
	int *p = new int[5];
	delete p;            //由于p是int类型,它没有有意义的析构函数,所以这里使用delete与delete[]是一样的 

placement new(定位new)

//placement new允许将对象创建于一个已经分配的内纯中,所以要有一个指针代表已经分配好的内存
	char* buf = new char[sizeof(Complex)*3]; //buf指针指向的就是提前分配好的内存 
	Complex* cp = new(buf)Complex();        //将pc创建在buf上,这样pc就不会重新分配内存 
	//Complex* cp = new(buf)Complex()也可写作如下 
	//Complex* cp;
	//try{
	//	void* men = operator new(sizeof(Complex), buf); //placement new
	//	cp = static_cast<Complex*>(men);
	//	cp->Complex::Complex();  //只有编译器可以这样做,所以这句我们使用时会报错 
	//}catch(std::bad_alloc){
	//	
	//}
	delete[] buf; //没有placement delete因为placement new根本没有分配内存 

 重载::operator new、::operator delete(不建议这样做)

不建议这样做,全局new与delete被重载的话影响无穷无尽。 

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

class Complex{
	public:
		int num;
		Complex(int _num) : num(_num){}
		Complex(){}
		~Complex(){}
};
void* myAlloc(size_t size){
	return malloc(size);
}
inline void* operator new(size_t size){
	cout << "调用了自己重载的new" << endl;
	return myAlloc(size);
} 

inline void* operator new[](size_t size){
	cout << "调用了自己重载的new" << endl;
	return myAlloc(size);
} 

void myFree(void* ptr){
	free(ptr);
} 

inline void operator delete(void* ptr){
	cout << "调用了自己重载的delete" << endl;
	myFree(ptr); 
}

inline void operator delete[](void* ptr){
	cout << "调用了自己重载的delete" << endl;
	myFree(ptr); 
}
int main(){
	//----------------重载new--------------------
	Complex* cp;								//这一步cp并没有指向 
	void* men = operator new(sizeof(Complex));
	cp = static_cast<Complex*>(men);			//这里cp指向了men开辟的内存 
	new(cp)Complex(5);							//在内存上建立对象 
	
	cout << cp->num << endl;
	
	operator delete(cp);
	return 0;
}

重载类的operator new、operator delete

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

class Foo{
	public:
		Foo(){}
		~Foo(){}
		
		void* operator new(size_t size){
			Foo *f = (Foo*)malloc(size);
			cout << "调用了自己重载的new" << endl;
			return f;
		} 
		void* operator new[](size_t size){
			Foo *f = (Foo*)malloc(size);
			cout << "调用了自己重载的new" << endl;
			return f;
		}
		
		void operator delete(void* ptr){
			cout << "调用了自己重载的delete" << endl; 
			free(ptr);
		}

		void operator delete[](void* ptr){
			cout << "调用了自己重载的delete" << endl;
			free(ptr);
		}
};


int main(){
	Foo* foo = new Foo[5];
	delete[] foo;
	return 0;
}

重载placement new

 

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

class Foo{
	public:
		int id;
		Foo(int i) : id(i){}
		Foo(){}
		~Foo(){}
		
		void* operator new(size_t size){
			Foo *f = (Foo*)malloc(size);
			cout << "operator new(size_t size)" << endl;
			return f;
		} 
		
		void* operator new(size_t size, void* start){
			cout << "operator new(size_t size, void* start)" << endl;
			return start;
		} 
		
		
		void* operator new(size_t size, long ers){
			cout << "operator new(size_t size, long ers)" << endl;
			return malloc(size + ers);
		} 
		
		void* operator new(size_t size, long ers, char ch){
			cout << "operator new(size_t size, long ers, char ch)" << endl;
			return malloc(size + ers);
		} 
		
		
		void* operator new[](size_t size){
			Foo *f = (Foo*)malloc(size);
			cout << "operator new[](size_t size)" << endl;
			return f;
		}
		
		void operator delete(void* ptr){
			cout << "operator delete(void* ptr)" << endl; 
			free(ptr);
		}
		
		void operator delete(void* ptr, long ers){
			cout << "operator delete(void* ptr, long ers)" << endl; 
			free(ptr);
		}
		
		void operator delete(void* ptr, long ers, char ch){
			cout << "operator delete(void* ptr, long ers)" << endl; 
			free(ptr);
		}

		void operator delete[](void* ptr){
			cout << "operator delete[](void* ptr)" << endl;
			free(ptr);
		}
};


int main(){
	Foo start;
	
	Foo* f1 = new(&start)Foo;
	Foo* f2 = new(100)Foo;
	Foo* f3 = new(100)Foo(2);
	Foo* f4 = new(100,'c')Foo;
	cout << start.id;
	return 0;
}

在重载placement new时,第一参数必须是size_t类型,并且最好写上其对应的重载delete.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!