爲了我的好奇心,我編寫了一個程序來顯示我的結構的每個字節。下面是代碼:在64位機器上的內存中的結構表示
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
#define MAX_INT 2147483647
#define MAX_LONG 9223372036854775807
typedef struct _serialize_test{
char a;
unsigned int b;
char ab;
unsigned long long int c;
}serialize_test_t;
int main(int argc, char**argv){
serialize_test_t *t;
t = malloc(sizeof(serialize_test_t));
t->a = 'A';
t->ab = 'N';
t->b = MAX_INT;
t->c = MAX_LONG;
printf("%x %x %x %x %d %d\n", t->a, t->b, t->ab, t->c, sizeof(serialize_test_t), sizeof(unsigned long long int));
char *ptr = (char *)t;
int i;
for (i=0; i < sizeof(serialize_test_t) - 1; i++){
printf("%x = %x\n", ptr + i, *(ptr + i));
}
return 0;
}
,這裏是輸出:
41 7fffffff 4e ffffffff 24 8
26b2010 = 41
26b2011 = 0
26b2012 = 0
26b2013 = 0
26b2014 = ffffffff
26b2015 = ffffffff
26b2016 = ffffffff
26b2017 = 7f
26b2018 = 4e
26b2019 = 0
26b201a = 0
26b201b = 0
26b201c = 0
26b201d = 0
26b201e = 0
26b201f = 0
26b2020 = ffffffff
26b2021 = ffffffff
26b2022 = ffffffff
26b2023 = ffffffff
26b2024 = ffffffff
26b2025 = ffffffff
26b2026 = ffffffff
,這裏是一個問題: 如果sizeof(long long int) is 8
,那麼爲什麼sizeof(serialize_test_t) is 24
,而不是32 - 我一直以爲結構的該尺寸舍入爲最大類型並乘以字段數,例如:8(字節)* 4(字段)= 32(字節) - 缺省情況下,沒有編譯指示包指令?
此外,當我將該結構轉換爲char *
時,我可以從輸出中看到內存中值之間的偏移量不是8個字節。你能給我一個線索嗎?或者,這可能只是一些編譯器優化?
你的假設是錯誤的。除了可能存在的標準之外,標準沒有對包裝或填充做任何說明。 –
填充要求不是C或者甚至是依賴於曲線的,但是依賴於ABI,您將很可能獲得特定於x86_64 ABI的答案,兩個主要的答案win64和System V(其他所有內容)將非常相似。 –
該標準說明了關於填充在結構中的一件事情:在結構的第一個元素之前不會有任何東西。除了第一個元素是由編譯器決定之前,是否有填充和其發生的位置。但對於任何結構類型'struct X x;','x'的地址也是'x'的第一個元素的地址(儘管地址類型不同)。 –