如何索引障碍分配
How to index obstack allocation
我试图索引由像数组这样的障碍物分配的内存,但我不知道我是否能做到这一点。它似乎分配了最小的 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 个字节。
Why would everything be offset?
计算机对允许数据在内存中的位置有规则,这称为对齐。不同类型的对齐方式不同,在系统 ABI 中指定。在我的机器 (AMD64 Linux) 上,对齐总是与字体大小相同,例如int 是 4 字节类型,因此它具有 4 字节对齐。这意味着 int 数据应始终从 4 的倍数的地址开始。因此 0x0004、0x000C、0x0010 将是有效的 int* 值,但不是 0x0006。
我猜想 16 字节只是您机器上任何类型的最大对齐方式。由于 obstack 类型不知道您将在其上放置什么数据,因此它必须为 16 字节类型的最坏情况保留 space。这也是 malloc() 和相关函数的情况,它们是 return 适合任何内置类型对齐的内存所必需的。
而且由于 obstack 几乎肯定会使用 malloc 来分配内存,因此它的内存也会以这种方式对齐。
有关详细信息,请参阅 spec on the AMD64 SysV ABI(如果这不是您的系统,则参阅等效文档)。
我试图索引由像数组这样的障碍物分配的内存,但我不知道我是否能做到这一点。它似乎分配了最小的 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 个字节。
Why would everything be offset?
计算机对允许数据在内存中的位置有规则,这称为对齐。不同类型的对齐方式不同,在系统 ABI 中指定。在我的机器 (AMD64 Linux) 上,对齐总是与字体大小相同,例如int 是 4 字节类型,因此它具有 4 字节对齐。这意味着 int 数据应始终从 4 的倍数的地址开始。因此 0x0004、0x000C、0x0010 将是有效的 int* 值,但不是 0x0006。
我猜想 16 字节只是您机器上任何类型的最大对齐方式。由于 obstack 类型不知道您将在其上放置什么数据,因此它必须为 16 字节类型的最坏情况保留 space。这也是 malloc() 和相关函数的情况,它们是 return 适合任何内置类型对齐的内存所必需的。
而且由于 obstack 几乎肯定会使用 malloc 来分配内存,因此它的内存也会以这种方式对齐。
有关详细信息,请参阅 spec on the AMD64 SysV ABI(如果这不是您的系统,则参阅等效文档)。