c - 内存分配头是否需要对齐 union ?

标签 c

在 K&R2 中,他们在第 8 章中实现了内存分配器。对于每个 block ,都有像这样定义的 header (根据内存,代码可能不准确):

union header_t
{
  struct 
  {
     unsigned size;
     unsigned* next; 
  };

  long align;
};

他们这样做是为了“确保标题在 long 的边界上正确对齐”。但是 union 不是由最大的成员结盟吗?该结构比单个对齐成员大,因此 header 无论如何都会按结构的倍数对齐,不是吗?

当结构更大时(比如它有很多成员)呢?在编写内存分配器时是否总是需要这种对齐 union 技巧?

最佳答案

K&R中的数据类型是:

union header
{
  struct 
  {
     union header *ptr; 
     unsigned size;
  } s;

  Align x;
};

假设我们有这个:

union header_t
{
  struct 
  {
     union header_t *next; 
     unsigned size;
  } s;
};

(顺便说一句,您需要为 struct 变量命名并更改 struct 中指向类型 union header_t * 的指针,因为 数据结构是一个链表。)

K&R的malloc()实现预留了一 block 空间,然后 使用它来维护免费商店。当这个 malloc 被调用时,它 在空闲列表中找到一个有足够空间的地方,并返回一个 指向它尾端的指针。

特别是,代码的相关部分是:

typedef union header Header;
static Header base;
Header *p = &base;
...
p += p->s.size;
return (void *)(p+1);

请注意,我们将返回 p+1(转换为 void *),因此我们必须确保此指针对于任何数据类型都是对齐的 。由于 p 本身指向一个 Header *,我们必须确保当我们将 sizeof(Header) 添加到一个对齐的指针时,我们返回另一个对齐的指针(记住,p+1 指向 p 中的 sizeof(Header) 字节)。此要求意味着 Header必须针对所有类型的数据进行对齐。

Header 内的struct 可能未针对可能的最宽类型对齐。为了确保我们的 Header 类型如此对齐,我们向 union 添加一个我们知道最大对齐的成员,即,是给定机器上最宽的类型. K&R 假设此类型是long。另外请注意,Header 的大小是否大于 Align 类型的大小并不重要。 这里的假设是这里的Align 类型是具有最严格对齐要求的类型,而不是它很大。

有趣的是,我们需要假设一个“最大对齐”类型,因为 C 标准要求对 malloc 返回的指针的任何类型进行对齐,但没有指定一种可移植的方法来找出对齐方式将是。如果标准确实指定了这样一种类型,则可以使用该类型而不是long 来实现Align

关于c - 内存分配头是否需要对齐 union ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1908024/

相关文章:

c - 在文件之间重置 Flex 扫描仪的正确方法

c - AVR GCC - 使用静态库 - undefined reference 错误

c++ - 精度损失(赋值)

不能让不同的编译器使用特定的头文件?

c - C 中使用 printf 打印宏变量

c - strtok 导致段错误

c - float 变量如何自动提升为 double 类型?

c - C 中的指针及其对数组的解释

c - 分配内存时内存泄漏

c - 如何在c中创建嵌套结构