2013-03-29 52 views
1
#include <stdio.h> 
#include <string.h> 
#include <malloc.h> 

struct Student { 
     char name[100]; 
     int id; 
     char major[50]; 
     char address[200]; 
}; 

int main() 
{ 

    struct Student st; 

    strcpy(st.name, "Chuck"); 
    st.id = 20001; 
    strcpy(st.major, "Computer Science"); 
    strcpy(st.address, "1st Street"); 

    printf("%d %d %d %d %d\n", sizeof(st), sizeof(st.name),sizeof(st.id), sizeof(st.major), sizeof(st.address)); 

    return 0; 
} 

輸出是356 100 4 50 200. 爲什麼sizeof(st)356而不是354? 我試過這個沒有int和輸出是350 100 50 200,所以我假設問題是在整數。sizeof in struct

+0

您沒有告訴您使用哪種編譯器,處理器,操作系統 –

+1

不要使用'%d'打印size_t's。改用'%zu'。 – Sebivor

+1

@BasileStarynkevitch:沒關係。所有平臺的答案都是一樣的。 –

回答

7

這是由於struct成員之間的填充引起的。填充是必要的,以確保每個數據成員正確aligned in memory。確切的對齊要求取決於您的架構。

因此,您不能假定struct的大小等於其成員大小的總和。

+0

「在你的特定情況下,int在四字節邊界對齊,需要兩個字節的填充」 - 不需要; 100%4 == 0。正確的答案是該結構對齊到4個字節的倍數(354%4 == 2)。 –

+0

@JimBalter:你說得很對,謝謝。 – NPE

+0

作爲一個方面說明,這也意味着結構中的成員聲明的順序可能會影響其大小。 –

1

結構中的每個非第一個字段之前可以有一個間隙(或填充)。編譯器正在增加空白以適應處理器和ABI約定的需要。

你應該信任編譯器,它按照實現的要求佈置struct

一些編譯器提供了擴展以改變或改進結構的佈局,例如, GCC的type attributesalignedpacked

不覺得struct裏面的填充和差距是一個問題,但作爲資產:編譯器試圖很難滿足處理器,ABI的約定,等...

大多數編譯器不對結構中的字段進行重新排序(GCC曾經有過很少有用的優化,但是這種優化已經被刪除,因爲有時它會受到傷害 - 例如LTO)。

如果您關心struct尺寸,並且您不關心字段的順序,可以巧妙地對它們進行重新排序。但最密集的順序可能依賴於架構。

順便說一下,C標準甚至不保證int是32位或者比char更大的尺寸和排列(即使這很常見)。它爲此提供了<stdint.h>int32_t。我懷疑如果編譯16位的機器(如80年代的Intel 8086處理器的原始PC AT或16位的微控制器),則不會觀察到任何填充或間隙。

+0

」結構中的每個非第一個字段之前可以有一個間隙(或填充)。「 - 在這種情況下,沒有一個字段前面有間隔;該差距出現在最後一個字段之後,以將結構大小填充到4的倍數。 –