我知道关于这个话题有很多问题,但我仍然感到困惑。
我编写了这个简单的程序来帮助我在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个字节。为什么在short
和char
之间还没有另外2个字节的填充?
另外,如果我使用4字节的对齐,为什么分配失败?由于这是struct
中最大元素的大小,不应该有效吗?
allocation failed
location of struct: (nil)
location of int: (nil)
location of short: 0x4
location of char: 0x6
sizeof struct: 8
答案 0 :(得分:1)
char
成员可以在任何字节边界上对齐;永远不需要在char
成员之前插入填充,即使编译器可以,如果它想要。它的布局方式,结构中只有一个填充字节。如果在short
成员之后存在间隙,则该结构将具有五个字节的填充,这是浪费的。
机器上posix_memalign()
支持的最小对齐可能是8。 POSIX说它可能会失败:
[EINVAL]
对齐参数的值不是sizeof(void *)
的两倍的幂。
话虽如此,看起来sizeof(void *)
可能是4(您打印的地址适合32位地址空间)。也许您应该打印errno
(和/或strerror(errno)
)以了解失败的原因。