可以使用offsetof()
宏从第一个成员(它必须具有与struct
相同的地址,因为不允许在第一个成员之前填充)找到每个字段的字节偏移量。
通过使用sizeof
运算符获得的信息与各种成员的大小(以及整个struct
的大小以查找尾部填充字节的数量),可以推导出填充字节的位置。这是一个打印出成员地址和偏移量的程序。它还打印成员字节和填充字节的图形表示;破折号表示填充字节。
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
struct simple_struct_1 {
long long a;
char b;
long c;
};
char * graph_member(char *ptr, size_t member_sz, size_t padding_sz);
int main(void)
{
struct simple_struct_1 my_struct;
printf("sizeof (struct simple_struct_1) = %zu\n",
sizeof (struct simple_struct_1));
putchar('\n');
void *ptra = &(my_struct.a);
void *ptrb = &(my_struct.b);
void *ptrc = &(my_struct.c);
size_t offset_a = offsetof(struct simple_struct_1, a);
size_t offset_b = offsetof(struct simple_struct_1, b);
size_t offset_c = offsetof(struct simple_struct_1, c);
/* Allocate memory for struct padding visualization */
char *graph = malloc(sizeof my_struct + 1);
if (graph == NULL) {
perror("Virtual memory exhausted");
exit(EXIT_FAILURE);
}
char *ptr = graph;
printf("&(my_struct.a) = %p\n", ptra);
printf("sizeof my_struct.a = %zu\n", sizeof my_struct.a);
putchar('\n');
ptr = graph_member(ptr,
sizeof my_struct.a,
offset_b - sizeof my_struct.a);
printf("&(my_struct.b) = %p\n", ptrb);
printf("sizeof my_struct.b = %zu\n", sizeof my_struct.b);
printf("&(my_struct.b) - &(my_struct.a) = %zu\n", offset_b - offset_a);
putchar('\n');
ptr = graph_member(ptr,
sizeof my_struct.b,
offset_c - offset_b - sizeof my_struct.b);
printf("&(my_struct.c) = %p\n", ptrc);
printf("sizeof my_struct.c = %zu\n", sizeof my_struct.c);
printf("&(my_struct.c) - &(my_struct.b) = %zu\n", offset_c - offset_b);
putchar('\n');
ptr = graph_member(ptr,
sizeof my_struct.c,
sizeof my_struct - offset_c - sizeof my_struct.c);
/* Null-terminate graph string and display */
ptr = '\0';
puts(graph);
free(graph);
return 0;
}
char * graph_member(char *ptr, size_t member_sz, size_t padding_sz)
{
/* Indicate member */
for (size_t i = 0; i < member_sz; i++) {
*ptr = '*';
++ptr;
}
/* Indicate padding */
for (size_t i = 0; i < padding_sz; i++) {
*ptr = '-';
++ptr;
}
return ptr;
}
样本程序输出:
sizeof (struct simple_struct_1) = 24
&(my_struct.a) = 0x7ffee4af4610
sizeof my_struct.a = 8
&(my_struct.b) = 0x7ffee4af4618
sizeof my_struct.b = 1
&(my_struct.b) - &(my_struct.a) = 8
&(my_struct.c) = 0x7ffee4af4620
sizeof my_struct.c = 8
&(my_struct.c) - &(my_struct.b) = 8
*********-------********
这看起来类似于[STRUCT存储器布局](https://stackoverflow.com/questions/2748995/c-struct-memory-layout) –
另外打印每个成员的'sizeof()'。它会在'char'中给你它们的大小。然后,您可以轻松推断地址中“char”的字节数。 – spectras
一般来说,使用或依赖特定内存布局的结构会产生错误的代码。 – StephenG