18.4 嵌入式指针概念及范例、内存池改进版

一:嵌入式指针(embedded pointer)

1、嵌入式指针概念

一般应用在内存池相关的代码中,成功使用嵌入式指针有个前提条件:(类A对象的sizeof必须不小于4字节)

嵌入式指针工作原理:借用A对象所占用的内存空间中前4个字节,这4个字节用来链住这些空闲的内存块;但是,一旦某一块被分配出去,那么这个块的前4个字节就不再需要,此时这4个字节可以被正常使用。



2、嵌入式指针演示代码

sizeof()超过4字节的类就可以安全的使用嵌入式指针(×64指针是8位)。

#include <iostream>

using namespace std;

class TestEP
{
public:
	int m_i;
	int m_j;
	int m_k;
	int m_l;

public:
	struct obj  //结构
	{
		//成员,是个指针
		struct obj* next;  //这个next就是个嵌入式指针
		//自己是一个obj结构对象,那么把自己这个对象的next指针指向另外一个obj结构对象,
		//最终,把多个自己这种类型的对象通过链串起来
	};
};

void func()
{
	TestEP mytest;
	cout << sizeof(mytest) << endl;  //8
	TestEP::obj* ptemp;  //定义一个指针
	ptemp = (TestEP::obj*)&mytest;  //把对象mytest首地址给了这个指针ptemp,这个指针ptemp指向对象mytest首地址
	cout << sizeof(ptemp->next) << endl;  //4
	cout << sizeof(TestEP::obj) << endl;  //4
	ptemp->next = nullptr;
}

struct test
{
public:
	test* pt;
};


int main()
{
	func();
}
TestEP mytest;
cout << sizeof(mytest) << endl;  //8
TestEP::obj* ptemp;  //定义一个指针
ptemp = (TestEP::obj*)&mytest;  //把对象mytest首地址给了这个指针ptemp,这个指针ptemp指向对象mytest首地址

&mytest 0x000000facff3f768 {m_i=-858993460 m_j=-858993460 m_k=-858993460 …}
&ptemp 0x000000facff3f798 {0x000000facff3f768 {next=0xcccccccccccccccc {next=??? }}}
&ptemp->next 0x000000facff3f768 {0xcccccccccccccccc {next=??? }}

ptemp->next = nullptr;

&ptemp 0x000000facff3f798 {0x000000facff3f768 {next=0x0000000000000000 }}
&(ptemp->next) 0x000000facff3f768 {0x0000000000000000 }

二:内存池代码的改进

单独的为内存池技术来写一个类

#include <iostream>

using namespace std;

//专门的内存池类
class MyAllocator  //必须保证应用本类的sizeof()不少于4字节,否则会崩溃或者报错
{
public:
	//分配内存接口
	void* allocate(size_t size)
	{
		obj* tmplink;
		if (m_freePosition == nullptr)
		{
			//为空,要申请一大块内存
			size_t realsize = m_sTrunkCount * size;  //申请m_sTrunkCount这么多倍的内存
			m_freePosition = (obj*)malloc(realsize);
			tmplink = m_freePosition;

			//把分配出来的这一大块内存(5小块),彼此链起来,供后续使用
			for (size_t i = 0; i < m_sTrunkCount - 1; i++)
			{
				tmplink->next = (obj*)((char*)tmplink + size);
				tmplink = tmplink->next;
			}
			tmplink->next = nullptr;
		}
		tmplink = m_freePosition;
		m_freePosition = m_freePosition->next;
		return tmplink;
	}

	//释放内存接口
	void deallocate(void* phead)
	{
		((obj*)phead)->next = m_freePosition;
		m_freePosition = (obj*)phead;
	}

private:
	//写在类内的结构,这样只让其在类内使用
	struct obj
	{
		struct obj* next;  //这个next就是个嵌入式指针
	};
	int m_sTrunkCount = 5;  //一次分配5倍的该类内存作为内存池的大小
	obj* m_freePosition = nullptr;
};

//------------------------------------------
#define DECLARE_POOL_ALLOC()\
public:\
	static MyAllocator myalloc;\
	static void* operator new(size_t size)\
	{\
		return myalloc.allocate(size);\
	}\
	static void operator delete(void* phead)\
	{\
		return myalloc.deallocate(phead);\
	}\
//------------------------------------------
#define IMPLEMENT_POOL_ALLOC(classname)\
MyAllocator classname::myalloc;
//------------------------------------------

class A
{
public:
	int m_i;
	int m_j;  //为了保证sizeof(A)凑够4字节,偃师市

public:
	DECLARE_POOL_ALLOC();
};

IMPLEMENT_POOL_ALLOC(A);

void func()
{
	A* mypa[100];
	for (size_t i = 0; i < 15; i++)
	{
		mypa[i] = new A();
		mypa[i]->m_i = 10;
		mypa[i]->m_j = 20;
		printf("%p\n", mypa[i]);
	}
	for (size_t i = 0; i < 15; i++)
	{
		delete mypa[i];
	}
}

int main()
{
	func();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值