分配自定义内存对齐的内存块的aligned_malloc实现分析

malloc一般使用当前平台默认的最大内存对齐数对齐内存,如MSVC在32bit下一般是8bit对齐;64位下则是16bit。这样对常规的数据来说没有问题。但如果我们自定义的内存对齐超出了这个范围,则不能直接使用malloc。当我们要分配一块具有特定内存对齐的内存块时,MSVC使用_aligned_malloc,而gcc使用memalign等函数。

《深入C++11 代码优化与工程应用》中给了自己实现aligned_malloc的方法,有些难以理解:

inline void* aligned_malloc(size_t size, size_t alignment)
{
	assert(!(alignment & (alignment - 1)));
	size_t offset = sizeof(void*) + (--alignment);
	cout << "sizeof(void*): " << sizeof(void*) << endl;

	char* reqBlockAddr = static_cast<char*>(malloc(offset + size));
	if (!reqBlockAddr) return nullptr;

	void* alignedAddr = reinterpret_cast<void*>(reinterpret_cast<size_t>(reqBlockAddr + offset) & (~alignment));
	cout << "alignedAddr: " << alignedAddr << endl;
	auto reqBlockAddrAddr = (void**)((size_t)alignedAddr - sizeof(void*));
	cout << "reqBlockAddrAddr: " << reqBlockAddrAddr << endl;

	*reqBlockAddrAddr = reqBlockAddr;
	cout << "reqBlockAddr: " << *reqBlockAddrAddr << endl;

	auto ori = static_cast<void**>(alignedAddr)[-1]; //ori == reqBlockAddr
	cout << "ori: " << ori << endl;

	//alignedAddr - reqBlockAddr = 4byte (32bit)
	//alignedAddr - reqBlockAddrAddr = 1byte (8bit)
	return alignedAddr;
}

inline void aligned_free(void* p)
{
	free(static_cast<void**>(p)[-1]);
}

int main(int argc, const char * argv[]) {

	aligned_malloc(100, 32);
	return 0;
}

该程序运行结果是:

其中参数size为要分配的内存块的大小,alignment为内存对齐的粒度,我们分别传入100,32。

先看第一句:!(alignment & (alignment - 1))表示对齐值必须是2^n:如果alignment是2^n,则alignment & (alignment - 1)必为0。因为2^n的二进制是100..(省略号表示后面都是省略号前的值,如0,下同),而2^n-1二进制是011...,两者进行与运算结果必为0,取反结果就是1了。

然后size_t offset = sizeof(void*) + (--alignment)是何意?sizeof(void*)是一个裸指针的大小,一般平台是1byte,其实这是个额外备用指针,先按下不表;而--alignment对于32来说是31,这个31的用意是:不论我需要的内存块多大,由于有了这个31byte的余量,我总能在这个0~31byte余量内找到内存对齐,即32byte的整数倍的内存的位置。

有了上面的offset,于是我们用malloc申请到的实际内存块大小是31+8+100=139byte,它的起始地址是reqBlockAddr。

但是reqBlockAddr是我们内部维护的整个内存块,并不是对外给用户提供的内存对齐到32byte的内存啊?于是通过运算reinterpret_cast<size_t>(reqBlockAddr + offset) & (~alignment),注意这里的alignment已经自减了(如31),结合刚刚所说31的意义,(reqBlockAddr + offset)即(reqBlockAddr + sizeof(void*) + (--alignment))这个地址不但剔除了个额外备用指针,还把31个byte的余量都剔除了,该地址到内存块末尾正好是我们申请的内存100byte。我们需要的是大于等于100byte的内存块,

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【乐吾乐2D可视化组态编辑器】图表动态显示

1. 添加数据 乐吾乐2D可视化组态编辑器地址&#xff1a;https://2d.le5le.com/ 图表动态展示是指一个图表图元的数据属性&#xff08;一般是dataY&#xff09;绑定多个变量&#xff0c;建立通信后数据动态变化展示。 官网默认Echarts图表拖拽到画布中是已经添加了图元的da…

OpenAI CTO米拉·穆拉提谈未来:AI一年半后达到博士水平

人工智能&#xff08;AI&#xff09;领域近年来的发展迅猛&#xff0c;特别是在大语言模型&#xff08;LLM&#xff09;的进步上。最近&#xff0c;OpenAI的首席技术官&#xff08;CTO&#xff09;米拉穆拉提&#xff08;Mira Murati&#xff09;在达特茅斯学院的一次采访中&am…

【Linux】Linux基础开发工具(yum)

Linux 软件包管理器 yum 什么是软件包 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序.但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安 装程序)放在一个服务器上, 通过包管理器可以很方便…

​Python20 Numpy基础

NumPy&#xff08;Numerical Python&#xff09;是一个开源的Python库&#xff0c;广泛用于科学计算。它提供了一个高性能的多维数组对象&#xff0c;以及用于处理这些数组的工具和函数。NumPy是数据分析、机器学习、工程和科学研究中不可或缺的工具之一&#xff0c;因为它提供…

【数据结构与算法】最小生成树,Prim算法,Kruskal算法 详解

最小生成树的实际应用背景。 最节省经费的前提下&#xff0c;在n个城市之间建立通信联络网。 Kruskal算法&#xff08;基于并查集&#xff09; void init() {for (int i 1; i < n; i) {pre[i] i;} }ll root(ll a) {ll i a;while (pre[i] ! i) {i pre[i];}return i p…

PaddleOCR C++源码编译以及demo测试

Windows10下使用PaddleOCRc 1.所需要的环境 PaddleOCR 源码文件&#xff1a;https://gitee.com/paddlepaddle/PaddleOCR &#xff08;本文选择2.6https://github.com/PaddlePaddle/PaddleOCR/archive/refs/tags/v2.6.0.zip&#xff09; opencv库&#xff1a;https://opencv…

将 Cohere 与 Elasticsearch 结合使用

本教程中的说明向你展示了如何使用推理 API 使用 Cohere 计算嵌入并将其存储起来&#xff0c;以便在 Elasticsearch 中进行高效的向量或混合搜索。本教程将使用 Python Elasticsearch 客户端执行操作。 你将学习如何&#xff1a; 使用 Cohere 服务为文本嵌入创建推理端点&…

swiper 幻灯片

index.html <!DOCTYPE html> <html lang"en"> <head> <meta charset"utf-8"> <title>swiper全屏响应式幻灯片代码</title> <meta name"viewport" content"widthdevice-width, initial-scale1, min…

reflutter工具实践之--xx一番赏app

此文章已经录制b站视频&#xff1a; flutter逆向案例-某某一番赏_哔哩哔哩_bilibili 一、工具介绍--reFlutter 这个框架帮助 Flutter 应用逆向工程&#xff0c;使用 Flutter 库的补丁版本&#xff0c;该版本已经编译并准备好重新打包应用。此库修改了快照反序列化过程&#…

Nature推荐的三种ChatGPT论文写作指令

1. 润色学术论文 ChatGPT学术润色指令&#xff1a; “I’m writing a paper on [topic]for a leading [discipline] academic journal. WhatItried to say in the following section is [specific point]. Please rephrase itfor clarity, coherence and conciseness, ensuri…

【源码】最新源支付系统源码 V7版全开源 免授权 附搭建教程

最新源支付系统源码_V7版全开源_免授权_附详细搭建教程_站长亲测 YPay是专为个人站长打造的聚合免签系统&#xff0c;拥有卓越的性能和丰富的功能。它采用全新轻量化的界面UI&#xff0c;让您能更方便快捷地解决知识付费和运营赞助的难题。同时&#xff0c;它基于高性能的thin…

【数据结构与算法】拓扑排序,关键活动,关键路径 详解

拓扑排序算法 bool topologicalSort() {stack<int> stk;int id[N];int cnt 0;for (int i 1; i < n; i) {if (!inDeg[i]) {stk.push(i);}id[i] inDeg[i];}while (stk.size()) {int t stk.top();stk.pop();cout << t << " ";cnt;for (auto i…

Java智慧工地源码 5G智慧工地系统源码 使用SAAS部署 三维可视化管理,与一线生产过程相融合,集成数据后台,统一前端入口,呈现多方项目信息;

Java智慧工地源码 5G智慧工地系统源码 使用SAAS部署 三维可视化管理&#xff0c;与一线生产过程相融合&#xff0c;集成数据后台&#xff0c;统一前端入口&#xff0c;呈现多方项目信息; 智慧工地是指运用信息化手段&#xff0c;通过三维设计平台对工程项目进行精确设计和施工…

【计划】软件项目总体计划书(项目必备资料合集原件)

项目开发计划包括项目描述、项目组织、成本预算、人力资源估算、设备资源计划、沟通计划、采购计划、风险计划、项目过程定义及项目的进度安排和里程碑、质量计划、数据管理计划、度量和分析计划、监控计划和培训计划等。 软件全套精华资料包清单部分文件列表&#xff1a; 工作…

智慧环保一体化平台登录

据悉&#xff0c;在当今这个数字化、智能化的时代&#xff0c;环境保护工作也需要与时俱进&#xff0c;不断创新。朗观视觉智慧环保一体化平台应运而生&#xff0c;它利用先进的信息技术手段&#xff0c;为环保工作提供了更加便捷、高效的管理方式&#xff0c;成为推动绿色发展…

移动端 UI 风格,诠释精致

移动端 UI 风格&#xff0c;诠释精致

【C++】————类和对象(上)

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;C 创作时间 &#xff1a;2024年6月21日 一、类与对象的初步认识 1、类其实就是对对象的抽象&#xff0c;而对象就是对类的具体实例 类不占用内存&#xff0c;而对象占用内存。 2、面向对象与面向过程 C语言是面…

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型&#xff08;LLMs&#xff09;&#xff0c;基本上是经过强化训练的 n-gram 模型&#xff0c;它们在网络规模的语言语料库&#xff08;实际上&#xff0c;可以说是我们文明的知识库&#xff09;上进行了训练&#xff0c;展现出了一种超乎预期的语言行为&#xff0c;引…

GMP合规下的纯蒸汽检查要点:三项值检测及冷凝水取样

制药企业进行纯蒸汽质量验证主要目的&#xff1a; 其一&#xff0c;为了确保药品生产过程的合规性&#xff0c;遵循GMP及国内外法规标准&#xff0c;验证纯蒸汽质量是关键环节。 其二&#xff0c;纯蒸汽质量直接影响药品的纯净度和安全性&#xff0c;验证工作能保障药品的质量…

双指针算法——滑动窗口

前言&#xff1a; 滑动窗口本质上也是利用双指针来解决特定情况下的问题。滑动窗口算法思想是通过俩个指针&#xff0c;定义在左边和右边&#xff0c;俩指针同向运动&#xff0c;保持着一个像“窗口”一样的双指针来不停的压缩或者扩展来移动“窗口”&#xff0c;从而找到特定…