如何在 C 中分配和释放对齐的内存

Posted

技术标签:

【中文标题】如何在 C 中分配和释放对齐的内存【英文标题】:How to allocate and free aligned memory in C 【发布时间】:2010-12-27 12:17:21 【问题描述】:

如何分配与 C 中特定边界对齐的内存(例如,缓存行边界)?我正在寻找类似 malloc/free 的实现,它在理想情况下应尽可能便携——至少在 32 位和 64 位架构之间。

编辑添加:换句话说,我正在寻找类似于(现在已过时?)memalign 函数的东西,可以使用 free 释放。

【问题讨论】:

您是否检查过这两个答案:***.com/questions/227897/… 和 ***.com/questions/1855896/…? 不是我想要的。我想要功能更像 malloc 的东西,返回一个值,即对齐的指针,然后有另一个类似于 free 的函数,在该指针上调用。应用您指出的解决方案需要传递两个值,或者在需要时重新计算对齐方式。我正在寻找类似于 memalign 的东西。感谢您指出这些答案。 在合适的机器上有posix_memalign() - 与memalign()有不同的界面。 aligned malloc() in GCC?的可能重复 【参考方案1】:

这里有一个解决方案,它封装了对 malloc 的调用,为对齐目的分配了一个更大的缓冲区,并将原始分配的地址存储在对齐的缓冲区之前以供以后调用 free。

// cache line
#define ALIGN 64

void *aligned_malloc(int size) 
    void *mem = malloc(size+ALIGN+sizeof(void*));
    void **ptr = (void**)((uintptr_t)(mem+ALIGN+sizeof(void*)) & ~(ALIGN-1));
    ptr[-1] = mem;
    return ptr;


void aligned_free(void *ptr) 
    free(((void**)ptr)[-1]);

【讨论】:

使用新标准,您应该考虑将转换为long 替换为uintptr_t @Jermoe 特别是代码在 64 位 Windows 上不起作用 @Jerome — 你说malloc(size+ALIGN+sizeof(void*)) 而不是malloc(size+ALIGN-1+sizeof(void*)) 有什么特别的原因吗?如果您要对齐 n 字节边界,那么您最多只需要 n – 1 个额外字节。 这段代码在 return 语句中使用 void** 有点令人困惑。 可以用+ALIGN-1代替+ALIGN吗? void aligned_malloc(int size) void *mem = malloc(size+ALIGN-1+sizeof(void)); void ptr = (void)((long)(mem+ALIGN-1+sizeof(void*)) & ~(ALIGN-1)); ptr[-1] = 内存;返回指针; 【参考方案2】:

使用posix_memalign/free

int posix_memalign(void **memptr, size_t alignment, size_t size); 

void* ptr;
int rc = posix_memalign(&ptr, alignment, size);
...
free(ptr)

posix_memalignmemalign 的标准替代品,正如您所提到的,它已经过时了。

【讨论】:

【参考方案3】:

你用的是什么编译器?如果你在 MSVC 上,你可以试试 _aligned_malloc()_aligned_free()

【讨论】:

Sun 的 Solaris/SPARC 编译器和 Linux/x86 的 gcc 编译器 看起来 Sun 支持 memalign():docs.sun.com/app/docs/doc/816-5168/malloc-3c?a=view 我没有看到任何迹象表明 memalign() 在当前 glibc 中已被弃用:cvs.savannah.gnu.org/viewvc/libc/malloc/… 有效链接:_aligned_free、_aligned_malloc。

以上是关于如何在 C 中分配和释放对齐的内存的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C 中分配 32 字节对齐的内存

如何在 C# 中释放在 C++ 中分配的内存

在复制构造函数中分配和初始化

Xcode 中的内存管理

什么是内存泄露?内存泄露如何解决?

ORACLE:在同一条语句中分配和检查