这篇文章将为大家详细讲解有关如何在c++项目中实现一个aligned_malloc方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
malloc的默认行为
int 主要() { void 才能;* p =, malloc (1024); ,,printf (“0 x % p \ n",, p); 免费的才能(p); }
请求了一个大小为1024的内存块并打印出来,一切都很完美。
我们看看这块内存的地址。
可以看的到,在64位机器上,malloc默认行为会将分配的地址以16字节对齐,如果我们想改变这种默认行为,提供32字节或者64字节对齐,应该怎么做呢?
实现aligned_malloc
源代码
从c++ 17开始,可以使用aligned_alloc函数达到这个目的,但是如果使用较老的c++版本,如c++ 14 C + + 11,我们需要手动写一个实现。
话不多说,先贴代码如下,aligned_malloc和aligned_free,需要配合使用,否则会有内存泄漏问题。
# include & lt; memory> void *, aligned_malloc (size_t 大小,size_t 对齐) { size_t offset =, alignment 作用;1,+,sizeof (void *); void *, originalP =, malloc(时间+ size 抵消); size_t originalLocation =, reinterpret_cast(originalP); size_t realLocation =,(时间+ originalLocation 抵消),,,~ (alignment 作用;1); 时间=void *, realP reinterpret_cast (p),背后,sizeof (void *); 免费的(* reinterpret_cast 添加一个测试程序,
# include & lt; assert.h> void TestAlignedMalloc () { const 才能int size =, 100; const 才能int alignment =, 64; ,,void *, testArray(大小); for 才能;(int 小姐:=,0;,小姐:& lt;,大小;,+ + i) {才能 ,,,void *, p =, aligned_malloc(1024年,对齐); ,,,断言((reinterpret_cast(p),,, (alignment 作用;1)),==,0); ,,,printf (“0 x % p \ n",, p); ,,,testArray[我],=,p; ,,} for 才能;(int 小姐:=,0;,小姐:& lt;,大小;,+ + i) {才能 ,,,aligned_free (testArray[我]); ,,} } int main () { TestAlignedMalloc才能(); return 才能;0; } 看看结果,
分配的内存地址都是以64字节为边界,并且分配的内存最后也被成功释放了,函数是正确的。
源代码说明
本小段主要向不大了解解决思路的小伙伴做一些简单解释,程序大佬可以一笑而过哈。
首先我们要明确我们的解决方案,既然malloc分配的指针地址不能达到我们想要的字节对齐效果,我们就自己来调整这个指针,所以我们的做法是
<李>
比用户实际需要的多分配一些内存,多分配的部分等于对齐大小减一再加上指针大小。加上对齐大小减一很好理解,是为了之后的对齐做准备,而加上指针大小是为了之后有空间保存原始指针,对应分配函数中的前2行
李> <李>在malloc返回的原始指针的基础上,加上指针大小,再对齐(采用的方法就是加上对齐大小减1再做位运算),这个运算结果就是我们想要的对齐后的指针,也是我们返回给用户的指针,对应分配函数中的3 ~ 5行
李> <李>我们还需要保存malloc返回的原始指针,否则免费的时候会出问题。这时我们之前多分配的一个指针大小就有用武之地了,保存原始指针在那个地址,分配函数的最后几行就在做这个事
李> <李>当免费的时候,我们知道原始指针存放在我们使用的指针的前一个指针大小偏移的内存里面,通过一些运算取得这个内存地址,再根据里面存放的原始指针调用免费完成内存释放
如何在c++项目中实现一个aligned_malloc方法