我试图索引像阵列一样的障碍分配的内存,但我不知道我是否能做到这一点。它似乎分配了最少16个字节,并且它总是16个字节的倍数。我可能只是对障碍的工作方式了解不足。
例如,此代码
#include <stdio.h>
#include <stdlib.h>
#include <obstack.h>
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
int main(void)
{
struct obstack ob_stack;
obstack_init(&ob_stack);
double a = 5.0;
double b = 24.0;
double c = 2.42;
double *pa = obstack_copy(&ob_stack, &a, sizeof a);
double *pb = obstack_copy(&ob_stack, &b, sizeof b);
double *pc = obstack_copy(&ob_stack, &c, sizeof c);
printf("%p %p %p\n", pa, pb, pc);
printf("%f %f %f %f %f %f\n", pa[0], pa[1], pa[2], pa[3], pa[4], pa[5]);
obstack_free(&ob_stack, NULL);
return 0;
}
输出:
0x683020 0x683030 0x683040
5.000000 0.000000 24.000000 0.000000 2.420000 0.000000
对我来说根本没有意义。为什么一切都会被抵消? 如果我改变分配大小,它会向上舍入到下一个16的倍数,即分配30个字节实际上分配32个字节。
答案 0 :(得分:1)
为什么一切都会被抵消?
计算机具有允许在内存数据中的位置的规则,这称为对齐。不同类型的对齐方式不同,在系统ABI中指定。在我的机器(AMD64 Linux)上,对齐始终与类型大小相同,例如int是一个4字节类型,因此它具有4字节对齐。这意味着int数据应始终以4的倍数开始。因此0x0004,0x000C,0x0010将是有效的int *值而不是0x0006。
我猜测16字节只是您机器上任何类型的最大对齐方式。由于obstack类型不知道您将在其上放置什么数据,因此它必须为16字节类型的最坏情况保留空间。 malloc()和相关函数也是如此,这些函数需要返回适合任何内置类型的内存。
因为obstack几乎肯定会使用malloc来分配内存,所以它的内存也会以这种方式对齐。
有关详细信息,请参阅spec on the AMD64 SysV ABI(如果这不是您的系统,请参阅等效文档)。