C++內存管理——侯捷老師課程系列源代碼

#C++內存管理

##per-class allocator,2

#include<iostream>
using namespace std;


class Screen {blic:
	Screen();
	Screen(int x) :i(x) {};
	int get() { return i; }
	void* operator new(size_t);
	void operator delete(void*, size_t);
private:
	Screen* next;
	int i;
	static Screen* freeStore;
    static const int screenChunk;
};
Screen* Screen::freeStore = 0;
 const int Screen::screenChunk = 24;
 Screen::Screen()
 {
	 i = 0;
	// next = (Screen *)malloc(sizeof (Screen));
	 next = 0;
 }
 /*
 Screen::Screen(int x)
 {
	 i = x;
	 next = (Screen*)malloc(sizeof(Screen));
 }
 */
void* Screen::operator new(size_t size)
{
	Screen* p;
	if (!freeStore)
	{
		//linked list 是空的,所以申請一大塊
		size_t chunk = screenChunk * size;
		freeStore = p = reinterpret_cast<Screen*>(new char[chunk]);
		//將一大塊分割片片,當做linked list 串接起來
		for (; p != &freeStore[screenChunk - 1]; ++p)
			p->next = p + 1;
		p->next = 0;
	}
	p = freeStore;
	freeStore = freeStore->next;
	return p;
}

void Screen::operator delete(void* p, size_t)
{
	//將deleted object插回 free list前端
	(static_cast<Screen*>(p))->next = freeStore;
	freeStore = static_cast<Screen*>(p);
}

int main()
{
	cout << sizeof(Screen) << endl;
	size_t const N = 100;
	Screen* p[N];

	for (int i = 0; i < N; ++i)
	{
		p[i] = new Screen(i);
	}
	for (int i = 0; i < 10; ++i)
		cout << p[i] << endl;
	cout << p[1] - p[0] << endl;
	cout << p[24] - p[0] << endl;
	cout << "p[23]:" << p[23] << endl;
	cout << "p[24]:" << p[24] << endl;
	cout << p[24] - p[23] << endl;

	for (int i = 0; i < 10; ++i)
		delete p[i];
	cout << "_______________________________\n";

	Screen* pt1[N];
	for (int i = 0; i < 10; i++)
		pt1[i] = ::new Screen(i);;
	for (int i = 0; i < 10; i++)
		cout << pt1[i] << endl;
	cout << pt1[1] - pt1[0] << endl;

	cout << "_______________________________\n";
	
	Screen* pt[N];
	for (int i = 0; i < 10; i++)
		pt[i] = (Screen*)malloc(sizeof(Screen));
	for (int i = 0; i < 10; i++)
		cout << pt[i] << endl;
	cout << pt1[1] - pt1[0] << endl;

	return 0;

}

#per-class allocator,2
另一個博主對這段代碼的詳細說明!

https://blog.csdn.net/zhangjing0502/article/details/7029851

#include<cstddef>
#include<iostream>
using namespace std;
static int times;

class Airplane{
private:
	struct AirplaneRep
	{
		unsigned long miles;
		char type;
	};
private:
	union {
		AirplaneRep rep;			//此欄針對使用中的objects
		Airplane* next;			//此欄針對free list 上的object
	};

public:
	unsigned long getMiles() { return rep.miles; }
	char getType() { return rep.type; }
	void set(unsigned long m, char t)
	{
		rep.miles = m;
		rep.type = t;
	}
public:
	Airplane()
	{ 
		next = 0;
	}
	static void* operator new(size_t size);
	static void operator delete(void *deadObject,size_t size);

	void operator<<(Airplane p[]);

private:
	static const int BLOCK_SIZE;
	static Airplane* headOfFreeList;	//跟蹤自由鏈表的表頭,表頭指針聲明爲靜態成員很重要,因爲整個類只有一個自由鏈表,而不是每個airplane對象都有
};

Airplane* Airplane::headOfFreeList;

const int Airplane::BLOCK_SIZE = 8;


void Airplane::operator<<(Airplane p[])//重載,沒有被指針正確調用
{
	cout << p << p->getMiles() << " " << p->getType() << endl;
}
void* Airplane::operator new(size_t size)
{
	//如果大小有誤,轉交給::operator new()
	if (size != sizeof(Airplane))
		return ::operator new(size);
	
	Airplane* p = headOfFreeList;
	if (p)//如果P有效,就把list頭部下移一個元素
		headOfFreeList = p->next;
	else
	{ 
		//freeList 已空,申請(分配)一大塊
		Airplane* newBlock = static_cast<Airplane*>(::operator new(BLOCK_SIZE * sizeof(Airplane)));

	//將小塊串成一個freeList
	//但跳過#0,因爲它將傳回作爲本次成果
	for (int i = 1; i < BLOCK_SIZE - 1; ++i)
		newBlock[i].next = &newBlock[i + 1];
	newBlock[BLOCK_SIZE - 1].next = 0;			//結束list
	p = newBlock;
	headOfFreeList = &newBlock[1];
	
	}


	//顯示每次headOfFreeList指針變量的變化,headOfFreeList指針將指針數組的地址用鏈表鏈接
	if(headOfFreeList)
	cout << "times:	" << times++ << " headOfFreeList address: " << headOfFreeList << "  next: " << headOfFreeList->next << endl;
	return p;

}

 void  Airplane::operator delete(void* deadObject, size_t size)
{
	 if (deadObject == 0)
		 return;
	 if (size != sizeof(Airplane))
	 {
		 ::operator delete(deadObject);
		 return;
	 }

	 Airplane* carcass =
		 static_cast<Airplane*>(deadObject);

	 carcass->next = headOfFreeList;
	 headOfFreeList = carcass;
	 cout << "times:	" << times-- << " headOfFreeList address: " << headOfFreeList << "  next: " << headOfFreeList->next << endl;
}

 int main()
 {
	 cout << sizeof(Airplane) << endl;

	 size_t const N = 10;
	 Airplane* p[N],*pt[N];
	 cout << "/*******顯示headOfFreeList指針變量的變化及調用次數*********/\n";
	 for (int i = 0; i < N; ++i)
		 p[i] = new Airplane;
	 cout << "/*******顯示headOfFreeList指針變量的變化及調用次數*********/\n";
	 //隨機測試object正常否
	 p[1]->set(1000, 'A');
	 p[5]->set(2000, 'B');
	 p[9]->set(500000, 'C');

	 //輸出前十個pointer
	 //用以比較期間隔
	 cout << "---------------operator new分配的內存間隔,不含cookie ------------------------\n";
	 for (int i =0; i < 10; ++i)
		 cout << "指針數組 "<<i<<":"<<p[i]<<"	miles:  "<<p[i]->getMiles()<<"	Type: "<<p[i]->getType()<<endl;

	 cout <<"指針數組間隔"<< p[1] - p[0] << endl;
	 cout << "---------------指針指向空間內存分配情況 ------------------------\n";
	 cout<<"p[1][1]: " << &p[1][1] << endl;
	 cout << "p[1][2]: " << &p[1][2] << endl;
	 cout << "p[1][3]: " << &p[1][3] << endl;
	 cout << "p[3][3]: " << &p[3][3] << endl;
	 cout << "p[3][4]: " << &p[3][4] << endl;
	 cout << "/*******顯示headOfFreeList指針變量的變化及調用次數*********/\n";
	 for (int i = 0; i < 10; ++i)
		delete p[i];
	 cout << "/*******顯示headOfFreeList指針變量的變化及調用次數*********/\n";

	 cout << "---------------malloc分配的內存間隔 ,含cookie------------------------\n";
	 for (int i = 0; i < N; ++i)
		 pt[i] = (Airplane * )malloc(sizeof(Airplane)* 8);

	 for (int i = 0; i < 10; ++i)
		 cout << "指針數組 " << i << ":" << pt[i] << endl;
	 cout << "指針數組間隔" << pt[1] - pt[0] << endl;
	 cout << "指針數組間隔" << pt[2] - pt[1] << endl;
	 cout << "指針數組間隔" << pt[3] - pt[2] << endl;

	 for (int i = 9; i < 10; ++i)
		 free(pt[i]);
	 cout << pt[5] << endl;

 }

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章