可以使用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