C++内存管理:内存池实现

示例1:在类中提前分配一块连续的内存池,减少cookie(分配内存时产生的头尾共8个字节,用于记录分配了多少内存)对内存的消耗

class Screen {
public:
	Screen(int x) : i(x) {}
	int getData() { return i; }
	void* operator new(size_t);
	void operator delete(void*, size_t);
private:
	static Screen* freeStore;//对象的内存地址
	static const int screenChunk;//要获取的Screen类的个数,内存数量 = sizeof(Screen) * screenChunk
	Screen* next;
	int i;
};
Screen* Screen::freeStore = nullptr;
const int Screen::screenChunk = 4;

void* Screen::operator new(size_t size){
	Screen* p;
	//freeStore不为空表示预先拿到的内存还有位置
	if (!freeStore) {
		size_t  chunk = size * screenChunk;
		freeStore = p = reinterpret_cast<Screen*>(new char[chunk]);
		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 size) {
	static_cast<Screen*>(p)->next = freeStore;
	freeStore = static_cast<Screen*>(p);
}

void test() {
	cout << "sizeof Screen: " << sizeof(Screen) << endl;//获取Screen大小
	Screen* p[100];
	for (int i = 0; i < 100; i++) {
		p[i] = new Screen(i);     //创建
	}
	for (int i = 0; i < 100; i++) {
		cout << "address: " << p[i] << "   i = " << p[i]->getData() << endl;
	}
	for (int i = 0; i < 100; i++) {
		delete p[i];              //销毁
	}
}

结果:screenChunk取值为4,所以每4个Screen对象的空间是连续的

C++内存管理:内存池实现

 示例2:例1的优化版,加入embedded pointer

class Airplane {
private:
	struct AirplaneRep {
		unsigned long miles;
		char type;
	};
	union {
		AirplaneRep rep;
		Airplane* next;
	};
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;
	}
	
	void* operator new(size_t size);
	void operator delete(void*, size_t);
private:
	static Airplane* headOfFreeList;
	static const int BLOCK_SIZE;
};
Airplane* Airplane::headOfFreeList = nullptr;
const int Airplane::BLOCK_SIZE = 512;

void* Airplane::operator new(size_t size){
	if (size != sizeof(Airplane)) {
		return ::operator new(size);
	}	
	Airplane* p = headOfFreeList;
	if (p) headOfFreeList = p->next;
	else {
		size_t total_size = size * BLOCK_SIZE;
		Airplane* newBLOCK = reinterpret_cast<Airplane*>(new char[total_size]);
		for (int i = 1; i < BLOCK_SIZE-1; i++)
			newBLOCK[i].next = &newBLOCK[i + 1];
		newBLOCK[BLOCK_SIZE - 1].next = 0;
		p = newBLOCK;
		headOfFreeList = &newBLOCK[1];
	}
	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;
}



void test() {
	const int size = 100000;
	cout << "sizeof Airplane: " << sizeof(Airplane) << endl;//获取Screen大小
	Airplane* p[size];
	for (int i = 0; i < size; i++) {
		p[i] = new Airplane();
		p[i]->set(i, i % 3);
	}
	for (int i = 0; i < size; i++) {
		cout << "address: " << p[i] << "   i = " << p[i]->getMiles() << endl;
	}
	for (int i = 0; i < size; i++) {
		delete p[i];//销毁
	}
}

示例3:采用一个类来进行内存池,让所有类都能共用

C++内存管理:内存池实现

C++内存管理:内存池实现

 示例4:加入宏定义

C++内存管理:内存池实现

 

上一篇:[JavaScript初级面试]7. WEB API - BOM(Browser Object Model)


下一篇:C++ 类的作用域