问题描述
这不是家庭作业,这纯粹是为了我自己的个人教育.
This is not homework, this is purely for my own personal education.
我不知道如何实现对齐的malloc,因此在线查看并发现此网站.为了便于阅读,我将在下面发布代码:
I couldn't figure out how to implement an aligned malloc so looked online and found this website. For the ease of reading I will post the code below:
#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);
}
该实现确实有效,但是老实说,我不知道它是如何工作的.
The implementation does work, but I honestly can't figure out how it works.
这是我不明白的地方:
- 为什么我们需要补偿?
-
~(alignment - 1)
的作用是什么 -
p2
是双指针.我们怎么能从应该只返回单个指针的函数中返回它呢? - 解决此问题的一般方法是什么?
- Why we need an offset?
- What does anding with
~(alignment - 1)
accomplish p2
is a double pointer. How come we can return it from a function that is supposed to return only a single pointer?- What is the general approach to solve this problem?
我们非常感谢您的帮助.
Any help is really appreciated.
编辑
这不是如何分配的副本,因为我还需要知道如何释放对齐的内存.
This is not a duplicate of How to allocate aligned memory only using the standard library? because I also need to know how to free aligned memory.
推荐答案
-
如果要支持超出系统
malloc()
功能的对齐方式,则需要一个偏移量.例如,如果系统malloc()
对齐8个字节的边界,而您想对齐16个字节,则要求额外增加15个字节,这样您就可以确定可以根据要求移动结果以使其对齐.您还可以将sizeof(void*)
添加到传递给malloc()
的大小上,以留出簿记空间.
You need an offset if you want to support alignments beyond what your system's
malloc()
does. For example if your systemmalloc()
aligns to 8 byte boundaries, and you want to align to 16 bytes, you ask for 15 bytes extra so you know for sure you can shift the result around to align it as requested. You also addsizeof(void*)
to the size you pass tomalloc()
to leave room for bookkeeping.
~(alignment - 1)
是保证对齐的原因.例如,如果对齐方式为16,则将1减去15得到15,也就是0xF,然后取反,得出0xFF..FF0,这是您需要满足malloc()
中返回的任何指针的对齐方式的掩码.请注意,此技巧假定对齐方式是2的幂(实际上通常是2的幂,但实际上应该进行检查).
~(alignment - 1)
is what guarantees the alignment. For example if alignment is 16, then subtract 1 to get 15, aka 0xF, then negating it makes 0xFF..FF0 which is the mask you need to satisfy the alignment for any returned pointer from malloc()
. Note that this trick assumes alignment is a power of 2 (which practically it normally would be, but there really should be a check).
这是void**
.该函数返回void*
.这是可以的,因为指向void的指针是指向任何类型的指针",在这种情况下,该类型为void*
.换句话说,允许将void*
与其他指针类型进行相互转换,并且双指针仍然是指针.
It's a void**
. The function returns void*
. This is OK because a pointer to void is "A pointer to any type," and in this case that type is void*
. In other words, converting void*
to and from other pointer types is allowed, and a double-pointer is still a pointer.
这里的总体方案是将原始指针存储在返回给调用方的指针之前.标准malloc()
的某些实现执行相同的操作:在返回的块之前隐藏簿记信息.这样就很容易知道调用free()
时需要回收多少空间.
The overall scheme here is to store the original pointer before the one that's returned to the caller. Some implementations of standard malloc()
do the same thing: stash bookkeeping information before the returned block. This makes it easy to know how much space to reclaim when free()
is called.
总而言之,这种事情通常是没有用的,因为标准malloc()
返回系统上最大的对齐方式.如果还需要对齐,则可能还有其他解决方案,包括特定于编译器的属性.
All that said, this sort of thing is usually not useful, because the standard malloc()
returns the largest alignment on the system. If you need alignment beyond that, there may be other solutions, including compiler-specific attributes.
这篇关于对齐malloc实现的说明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!