如何使用posix_memalign在C中正确对齐结构?

时间:2014-12-15 04:09:37

标签: c memory-management struct alignment posix

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

我编写了这个简单的程序来帮助我在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;
}

这很好用,但我对这些路线感到困惑。

使用这些参数(alignment = 8 bytes,size = 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

1 个答案:

答案 0 :(得分:1)

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

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

  

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

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