【发布时间】:2014-11-02 16:20:26
【问题描述】:
我有一个包含不同类型成员的庞大结构。我知道成员是根据他们的类型对齐的。
有没有办法弄清楚差距在哪里?
我的意思是我很想知道编译器在哪些成员之间插入了一个间隙(当然间隙大小是多少)。
【问题讨论】:
标签: c struct memory-alignment
我有一个包含不同类型成员的庞大结构。我知道成员是根据他们的类型对齐的。
有没有办法弄清楚差距在哪里?
我的意思是我很想知道编译器在哪些成员之间插入了一个间隙(当然间隙大小是多少)。
【问题讨论】:
标签: c struct memory-alignment
它取决于平台,您可以使用 offsetof 宏通过一个小型测试程序来确定它,或者对于大多数 Unix 系统,您可以参考您架构的 System V ABI 文档。
一般来说,额外的空间会立即插入到任何可能会不正确对齐的成员之前,而不进行任何重新排序,如果会导致数组中的下一个结构不正确对齐,则在最后插入。
struct s { short a; int b; };
offsetof(struct s, a) == 0
offsetof(struct s, b) == 4 // for example
sizeof(short) == 2
间隙是 a 和 b 之间的两个字节。
要检测结构末尾的填充,只需查看结构的大小以及最后一个元素的偏移量和大小。
struct s2 { int a; short b; };
offsetof(struct s2, b) == 4
sizeof(struct s2) == 8
【讨论】:
使用stddef.h中定义的offsetof()
struct my
{
float f ;
double d ;
} ;
这会在 f 和 d 之间填充:
size_t p = offsetof(struct my , d) - ( offsetof(struct my , f) + sizeof(float) );
对结构的每个成员执行此操作。
【讨论】:
如果您不想使用 offsetof 宏,您可以通过获取指针并将全部转换为 char * 来实现困难。示例:
#include <stdio.h>
struct my_struct {
char c;
short h;
char c2;
long l;
};
void display(FILE *fd) {
struct my_struct ms;
int delta1 = (char *)(void *) &ms.h - (char *)(void*) &ms.c;
int gap1 = delta1 - sizeof(char);
int delta2 = (char *)(void *) &ms.c2 - (char *)(void*) &ms.h;
int gap2 = delta2 - sizeof(short);
int delta3 = (char *)(void *) &ms.l - (char *)(void*) &ms.c2;
int gap3 = delta3 - sizeof(char);
int gap4 = sizeof(ms) -sizeof(long) - ((char *)(void *) &ms.l - (char *)(void*) &ms);
fprintf(fd, "char to short : %d - short to char %d - char to long %d - struct to struct : %d\n",
gap1, gap2, gap3, gap4);
}
int main() {
display(stderr);
}
给:
char to short : 1 - short to char 0 - char to long 3 - struct to struct : 0
【讨论】: