我正在使用C语言开发一个项目,它需要memalign()。真的,posix_memalign()也会这样做,但是darwin / OSX缺乏这两者。
什么是鞋拔的好方法?我不理解posix-C代码的许可,如果我要删掉memalign.c并把它放在我的项目中 - 我不希望任何病毒式许可LGPL整个项目。
答案 0 :(得分:13)
Mac OS X似乎是16-byte mem aligned.
来自网站的引用:
我很难找到确定的 关于MacOS X内存对齐的声明 所以我做了自己的测试。在10.4 / intel, 堆栈和堆内存都是16字节 对齐。所以人们移植软件 可以停止寻找memalign()和 posix_memalign()。这不是必需的。
答案 1 :(得分:8)
posix_memalign()
晚会,但较新版本的OSX 做有posix_memalign()
。在对齐页面边界时,您可能需要这样做。例如:
#include <stdlib.h>
char *buffer;
int pagesize;
pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize == -1) handle_error("sysconf");
if (posix_memalign((void **)&buffer, pagesize, 4 * pagesize) != 0) {
handle_error("posix_memalign");
}
需要注意的一点是,与memalign()
不同,posix_memalign()
将**buffer
作为参数并返回整数错误代码。
答案 2 :(得分:6)
应该很容易做到自己,不是吗?类似于以下内容(未经测试):
void *aligned_malloc( size_t size, int align )
{
void *mem = malloc( size + (align-1) + sizeof(void*) );
char *amem = ((char*)mem) + sizeof(void*);
amem += align - ((uintptr)amem & (align - 1));
((void**)amem)[-1] = mem;
return amem;
}
void aligned_free( void *mem )
{
free( ((void**)mem)[-1] );
}
(谢谢Jonathan Leffler)
修改强> 关于剥夺另一个memalign实现,问题不在于许可。相反,你遇到的困难是任何好的memalign实现都将成为堆管理器代码库不可或缺的一部分,而不是简单地分层在malloc / free之上。因此,将它移植到不同的堆管理器时会遇到严重问题,尤其是当您无法访问它的内部时。
答案 3 :(得分:3)
为什么要移植的软件需要memalign()或posix_memalign()?是否将它用于大于austirg引用的16字节对齐的对齐?
我看到Mike F发布了一些代码 - 它看起来相对简洁,但我认为while循环可能是次优的(如果所需的对齐是1KB,它可能会迭代很多次)。
不
amem += align - ((uintptr)amem & (align - 1));
在一次手术中到达那里?
答案 4 :(得分:2)
来自macosx手册页:
malloc(),calloc(),valloc(), realloc()和reallocf()函数 分配内存。分配的内存对齐,以便它可以 用于任何数据类型,包括AltiVec-和SSE相关类型。免费() 函数释放通过前面的分配创建的分配 功能
答案 5 :(得分:1)
是 ABI 中的Mac OS X 确实有16个字节内存对齐。 你不应该使用memalign()。如果你的内存需求是16的因素,那么我就不会实现它,也许只是添加一个断言。
答案 6 :(得分:1)
如果你需要一个任意对齐的malloc,请查看x264的malloc(git存储库中的common / common.c),它有一个没有malloc.h的系统的自定义memalign。它非常简单的代码,我甚至不认为它具有版权,但你应该很容易在看到它之后实现自己的代码。
当然,如果您只需要16字节对齐,如上所述,它在OS X ABI中。
答案 7 :(得分:1)
可能值得建议在代码中使用Doug Lea的malloc。 link text
答案 8 :(得分:0)
感谢您的帮助,伙计......帮助我(OpenCascade src / Image / Image_PixMap.cxx,OSX10.5.8 PPC)
结合上面的答案,如果不是特别熟悉malloc等,这可能会节省一些人在挖掘或灌输希望:
我正在构建的相当大的项目只有一个对posix_memalign的引用,结果发现它是一堆预处理器条件的结果,不包括OSX但是DID包括BORLANDC,这证实了其他人对它的建议在某些情况下使用malloc是安全的:
#if defined(_MSC_VER)
return (TypePtr )_aligned_malloc (theBytesCount, theAlign);
#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
return (TypePtr ) _mm_malloc (theBytesCount, theAlign);
#elif defined(__BORLANDC__)
return (TypePtr ) malloc (theBytesCount);
#else
void* aPtr;
if (posix_memalign (&aPtr, theAlign, theBytesCount))
{
aPtr = NULL;
}
return (TypePtr )aPtr;
#endif
因此,它可以像使用malloc一样简单,正如其他人所建议的那样。
e.g。在此处:将__BORLANDC__
条件移至__GNUC__
以上并添加 APPLE :
#elif (defined(__BORLANDC__) || defined(__APPLE__)) //now above `__GNUC__`
注意:我做了 NOT 检查BORLANDC使用16字节对齐,就像上面提到的操作系统X所做的那样。我也没有验证PPC OS X的确如此。但是,这种用法表明这种对齐并不是特别重要。 (这里希望它有效,而且搜索者也可以这么容易!)