【问题标题】:How to correctly align structs in C using posix_memalign?如何使用 posix_memalign 正确对齐 C 中的结构?
【发布时间】:2015-02-13 03:30:30
【问题描述】:

我知道关于这个话题有很多问题,但我仍然感到困惑。

我编写了这个简单的程序来帮助我在 C 中可视化内存对齐:

#include <stdio.h>
#include <stdlib.h>
struct S{
  int a;    
  short b;
  char c;
};
int main()
{
    struct S *s;
    posix_memalign((void**)&s, 8, 12) == 0 ? printf("allocation successful"):printf("allocation failed");
    printf("\nlocation of struct:\t%p\n", s);
    printf("\nlocation of int:\t%p\nlocation of short:\t%p\nlocation of char:\t%p\n", &(s->a), &(s->b), &(s->c));
    printf("\nsizeof struct: %lu\n", sizeof(s));
    free(s);
    return 0;
}

这很好用,但我对对齐感到困惑。

使用这些参数(对齐=8 字节,大小=12):

allocation successful
location of struct: 0x205e010

location of int:    0x205e010
location of short:  0x205e014
location of char:   0x205e016

sizeof struct: 8

int 是结构的最大元素,占 4 个字节。我可以在这里看到short 开始于 4 个字节之后,char 开始于 2 个字节之后。为什么shortchar 之间没有另外 2 个字节的填充?

另外,如果我使用 4 字节对齐,为什么分配会失败?既然这是struct 中最大元素的大小,难道不应该工作吗?

allocation failed
location of struct: (nil)

location of int:    (nil)
location of short:  0x4
location of char:   0x6

sizeof struct: 8

【问题讨论】:

  • 我很好奇:你为什么要分配一个硬编码的12 字节而不是sizeof(struct S) 字节?

标签: c memory-management struct alignment posix


【解决方案1】:

char 成员可以在任何字节边界上对齐;永远不需要在 char 成员之前插入填充,即使编译器可以根据需要插入。它的布局方式,结构中只有一个填充字节。如果在short 成员之后有一个间隙,则该结构将有五个字节的填充,这是一种浪费。

posix_memalign() 在您的机器上支持的最小对齐可能是 8。 POSIX 说它可能会失败:

[EINVAL] 对齐参数的值不是sizeof(void *) 的两个倍数的幂。

话虽如此,看起来sizeof(void *) 可能是 4(您打印的地址适合 32 位地址空间)。也许你应该打印errno(和/或strerror(errno))来看看失败的原因是什么。

【讨论】:

  • 谢谢,关于字符对齐很有趣。我没有读过那个。我不明白为什么 4 的对齐会失败,但是 int 和 short 仍然被 4 个字节分隔。打印 strerror(errno) 刚刚给了我:成功。即对齐设置为 4,大小设置为 12。
  • 另外,我知道 sizeof(void*) 是 8 个字节。
  • @user2676680: 鉴于sizeof(void *) 是 8 个字节,那么您不能以 4 个字节的奇数倍对齐分配;它不符合 POSIX 指定的要求。
猜你喜欢
  • 2021-11-16
  • 2019-01-30
  • 1970-01-01
  • 2014-12-01
  • 2022-06-23
  • 1970-01-01
  • 2013-07-25
  • 1970-01-01
  • 2013-07-24
相关资源
最近更新 更多