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

news2025/7/18 14:09:35

一:嵌入式指针(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();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/38004.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文华财经期货K线多周期画线技术,多重短线技术共振通道线指标公式——多周期主图自动画线

期货指标公式是通过数学逻辑角度计算而来&#xff0c;仅是期货分析环节中的一个辅助工具。期货市场具有不确定性和不可预测性的&#xff0c;请正常对待和使用指标公式! 期货指标公式信号本身就有滞后性&#xff0c;周期越大&#xff0c;滞后性越久。指标公式不是100%稳赚的工具…

cocos2dx创建工程并在androidstudio平台编译

本文主要是通过androidstudio进行编译运行cocos2dx工程。 前置条件&#xff1a; 1&#xff1a;androidstudio已经下载并安装。 2&#xff1a;cocos2dx已经下载并打开。 这里androidstudio使用2021.3.1版本&#xff0c;cocos2dx使用4.0版本。 第一步&#xff0c;首先安装py…

Hive之数据类型和视图

Hive系列 第八章 数据类型和视图 8.1 数据类型 8.1.1 原子数据类型 &#xff08;其实上图中有一点错误&#xff0c;大家可以找找看&#xff09; 说明&#xff1a; 1、Hive 支持日期类型(老版本不支持)&#xff0c;在 Hive 里日期一般都是用字符串来表示的&#xff0c;而常用…

STC 51单片机40——汇编语言 串口 接收与发送

实际运行&#xff0c;正常 ; 仿真时&#xff0c;单步运行&#xff0c;记得设置虚拟串口数据【仿真有问题&#xff0c;虚拟串口助手工作不正常&#xff01;】 ORG 0000H MOV TMOD ,#20H ;定时器1&#xff0c;工作方式2&#xff0c;8位重装载 MOV TH1,#0FDH ; 波特率…

智慧酒店解决方案-最新全套文件

智慧酒店解决方案-最新全套文件一、建设背景为什么要建设智慧酒店一、智慧酒店功能亮点 &#xff1a;二、智慧酒店八大特色&#xff1a;二、建设思路三、建设方案四、获取 - 智慧酒店全套最新解决方案合集一、建设背景 为什么要建设智慧酒店 一、智慧酒店功能亮点 &#xff1…

mysql-8.0.31-macos12-x86_64记录

常用的命令 停止MySQL服务 : sudo /usr/local/mysql/support-files/mysql.server stop 启动MySQL服务 : sudo /usr/local/mysql/support-files/mysql.server start 重启MySQL服务 : sudo /usr/local/mysql/support-files/mysql.server restart 修改mysql密码 关闭mysql服务…

Qt5开发从入门到精通——第十二篇二节(Qt5 事件处理及实例——多线程控制、互斥量、信号量、线程等待与唤醒)

提示&#xff1a;欢迎小伙伴的点评✨✨&#xff0c;相互学习c/c应用开发。&#x1f373;&#x1f373;&#x1f373; 博主&#x1f9d1;&#x1f9d1; 本着开源的精神交流Qt开发的经验、将持续更新续章&#xff0c;为社区贡献博主自身的开源精神&#x1f469;‍&#x1f680; 文…

【C语言数据结构】带头节点与不带头节点的单链表头插法对比

前言 近期在学习STM32代码框架的过程中&#xff0c;老师使用链表来注册设备&#xff0c;发现使用了不带头节点的单链表&#xff0c;注册时使用头插法。之前在本专题整理学习过带头节点的单链表&#xff0c;因此本文整理对比一下两种方式的头插法区别&#xff0c;具体实现在次&…

html表白代码

目录一.引言二.表白效果展示1.惊喜表白2.烟花表白3.玫瑰花表白4.心形表白5.心加文字6.炫酷的特效一.引言 我们可以用一下好看的网页来表白&#xff0c;下面就有我觉得很有趣的表白代码。评论直接找我要源码也行。 下载整套表白文件 二.表白效果展示 1.惊喜表白 2.烟花表白 源码…

【TS】泛型以及多个泛型参数

泛型 给函数或者属性定义类型的时候&#xff0c;类型是固定的&#xff0c;当业务发生变动时可能不好维护&#xff0c;例如&#xff1a;函数类型固定为string,后续需求更改不好维护&#xff0c;比如需要传入number类型&#xff0c;那么这个函数就不适用了 function add( val :…

数学题类英语作文

最近我看到过这样一道英语作文题&#xff0c;这类英语作文题很少见&#xff0c;但也有必要讲一讲怎么写。 简化题意&#xff1a;帮Peter完成一下一道题&#xff1a; f(x)ax2−(a6)x3ln⁡xf(x)ax^2-(a6)x3\ln xf(x)ax2−(a6)x3lnx &#xff08;1&#xff09;讨论当a1a1a1时&am…

CMake中file的使用

CMake中的file命令用于文件操作&#xff0c;其文件格式如下&#xff1a;此命令专用于需要访问文件系统的文件和路径操作 Readingfile(READ <filename> <variable>[OFFSET <offset>] [LIMIT <max-in>] [HEX])file(STRINGS <filename> <variab…

Java8-新特性及Lambda表达式

1、Java8新特性内容概述 1.1、简介 Java 8(又称为jdk1.8)是Java语言开发的一个主要版本 Java 8是oracle公司于2014年3月发布&#xff0c;可以看成是自Java 5以来最具革命性的版本。Java 8为Java语言、编译器、类库、开发工具与JVM带来了大量新特性 1.2、新特性思维导图总结 1.…

JS中数组随机排序实现(原地算法sort/shuffle算法)

&#x1f431;个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️作者简介&#xff1a;专注于前端领域各种技术&#xff0c;热衷分享&#xff0c;期待你的关注。 &#x1f4ab;系列专栏&#xff1a;vue3从入门到精通 &#x1f4dd;个人签名&#xff1a;不破不立 目录一、原地…

代码随想录刷题|LeetCode 70. 爬楼梯(进阶) 322. 零钱兑换 279.完全平方数 139.单词拆分

目录 70. 爬楼梯 &#xff08;进阶&#xff09; 思路 爬楼梯 1或2步爬楼梯 多步爬楼梯 322. 零钱兑换 思考 1、确定dp数组及其含义 2、确定递推公式 3、初始化dp数组 4、确定遍历顺序 零钱兑换 先遍历物品&#xff0c;再遍历背包 先遍历背包&#xff0c;再遍历物品 279.完全平方…

【操作系统实验】线程的创建+信号量通信

sem_init: 功能&#xff1a;初始化信号量 返回值&#xff1a;创建成功返回0&#xff0c;失败返回-1 参数sem&#xff1a;指向信号量结构的一个指针 参数pshared&#xff1a;不为&#xff10;时此信号量在进程间共享&#xff0c;为0时当前进程的所有线程共享 参数value&#xf…

react context原理

带着问题思考&#xff1a; 1 Provder 如何传递 context&#xff1f;2 三种获取 context 原理 &#xff08; Consumer&#xff0c; useContext&#xff0c;contextType &#xff09;&#xff1f;3 消费 context 的组件&#xff0c;context 改变&#xff0c;为什么会订阅更新 &a…

Vue+iview将表格table以excel文件导出的几种方式

前言 在日常工作中&#xff0c;若是经常跟后台管理系统打交道的朋友想必对导出excel表格这种需求肯定很熟悉吧。不过我也问了身边的一些岗位为后端工程师的朋友&#xff0c;他们说在公司的话一般导出excel表格的工作一般由后端来做&#xff0c;前端只需要调用接口即可。我的话…

AI面试必备-《家居必备的AI精选资源列表》免费分享

本资源介绍 DeepMind科学家和工程师为有兴趣了解更多人工智能、机器学习和其他相关主题的学生整理的教育资源列表。 文末附本书免费获取地址。 内容截图 本资源免费下载地址 链接: https://pan.baidu.com/s/1IkPk0a3q2Z1z4FATG2y7HA?pwdwy3c 提取码: wy3c 往期精品内容推荐 大…

认知电子战 | 无线电中的认知理论

认知的概念 认知(Cognition)是指人认识外界事务的过程 认知本来是用于描述具有生命特征的物种的,借用于机器或系统上,就是指将认知的思想应用于机器上。 生物的认知特点: 感觉思考、推理、问题解答判断记忆分别对应于系统认知特点: 感知(各种传感器)机器学习算法、基…