这不是作业,这纯粹是为了我自己的个人教育。
我不知道如何实现对齐的 malloc 所以在网上查找并发现这个网站 https://sites.google.com/site/ruslancray/lab/bookshelf/interview/ci/low-level/write-an-aligned-malloc-free-function。为了方便阅读,我将发布以下代码:
#include <stdlib.h>
#include <stdio.h>
void* aligned_malloc(size_t required_bytes, size_t alignment)
{
void* p1; // original block
void** p2; // aligned block
int offset = alignment - 1 + sizeof(void*);
if ((p1 = (void*)malloc(required_bytes + offset)) == NULL)
{
return NULL;
}
p2 = (void**)(((size_t)(p1) + offset) & ~(alignment - 1));
p2[-1] = p1;
return p2;
}
void aligned_free(void *p)
{
free(((void**)p)[-1]);
}
void main (int argc, char *argv[])
{
char **endptr;
int *p = aligned_malloc (100, strtol(argv[1], endptr, 10));
printf ("%s: %p\n", argv[1], p);
aligned_free (p);
}
该实现确实有效,但老实说我不知道它是如何工作的。
这是我无法理解的:
- 为什么我们需要偏移量?
- anding 和 是什么
~(alignment - 1)
完成
-
p2
是一个双指针。为什么我们可以从一个应该只返回单个指针的函数中返回它?
- 解决这个问题的一般方法是什么?
非常感谢任何帮助。
EDIT
这不是重复的如何仅使用标准库分配对齐内存? https://stackoverflow.com/questions/227897/how-to-allocate-aligned-memory-only-using-the-standard-library因为我还需要知道如何释放对齐的内存。
-
如果您想支持超出系统范围的对齐,则需要偏移量malloc()
做。例如,如果您的系统malloc()
对齐到 8 字节边界,并且您想要对齐到 16 字节,您要求额外 8 个字节,这样您就可以确定可以移动结果以按要求对齐。您还添加sizeof(void*)
到你传递给的大小malloc()
为簿记留出空间。
-
~(alignment - 1)
是保证对齐的原因。例如,如果对齐方式为 16,则减去 1 得到 15,即 0xF,然后对其求反,得到 0xFF..FF0,这是您需要满足从以下位置返回的任何指针的对齐方式的掩码:malloc()
。请注意,这个技巧假设对齐是 2 的幂(实际上通常是这样,但确实应该进行检查)。
-
It's a void**
。函数返回void*
。这是可以的,因为指向 void 的指针是“指向任何类型的指针”,在这种情况下,该类型是void*
。换句话说,转换void*
允许往返于其他指针类型,并且双指针仍然是指针。
-
这里的总体方案是将原始指针存储在返回给调用者的指针之前。标准的一些实现malloc()
做同样的事情:在返回的块之前存储簿记信息。这使得很容易知道何时回收多少空间free()
叫做。
话虽如此,这种事情通常没有用,因为标准malloc()
返回系统上最大的对齐方式。如果您需要除此之外的对齐,可能还有其他解决方案,包括特定于编译器的属性。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)