2016-09-01 27 views
2

由於存在一些無關標誌(sta_scan,search),它們在下面的結構中定義爲位域。這些標誌被宣佈的位置是否重要(在內存保存方面)?結構中的位域位置

struct sta_all { 
    char name[16]; 
    unsigned int sta_scan:1; 
    ... 
    int interval; 
    unsigned int search:1; 
} 
+2

這些位字段中的每一個都可能被分配與基本類型('unsigned int')相同的空間,並將使用該存儲單元中的32位(16,64,...)位中的一位。如果你決定使用位域,你應該確保所有的位域聚集在一起;它會盡量減少浪費的空間。你應該考慮'bool'(來自''還是'_Bool')是否也可以用於你的目的,或者更好。許多有關位字段的細節都是實現定義的,但在結構的上下文中,編譯器沒有自由移動位字段。 –

+0

編譯器不允許[重新排序struct成員](http://stackoverflow.com/q/9486364/995714),所以你需要自己去做,除非你啓用了一些[編譯器選項](http://stackoverflow.com/q/14671253/995714) –

+0

artM很好的問題,我從昨天晚上開始編輯我的答案,而不是在牀上數羊,我只是在數點數,希望你會發現它有幫助! :) – gsamaras

回答

3

,但並非總是如此。


檢查這個例子:

#include <stdio.h> 
#include <string.h> 

struct { 
    char name[16]; 
    unsigned int sta_scan:1; 
    int interval; 
    unsigned int search:1; 
} sta_all; 

int main() { 

    sta_all.interval = 4; 
    printf("Sizeof(sta_all) : %zu\n", sizeof(sta_all)); 

    return 0; 
} 

輸出:

的sizeof(sta_all):28

和:

#include <stdio.h> 
#include <string.h> 

struct { 
    char name[16]; 
    unsigned int sta_scan:1; 
    unsigned int search:1; 
    int interval; 
} sta_all; 

int main() { 

    sta_all.interval = 4; 
    printf("Sizeof(sta_all) : %zu\n", sizeof(sta_all)); 

    return 0; 
} 

輸出:

的sizeof(sta_all):24

發生這種情況是因爲填充on my platform。順便說一句,如果你真的非常渴望記憶效率,並且你可以接受速度損失,那麼你可以使用包裝,正如上面的鏈接所解釋的那樣。

注:上面的例子證實了在提到Jonathan Lefflercomment

那些位字段中的每一個可能被分配儘可能多的空間的基本類型(unsigned int)並且將使用32 1 (16,64,...)位。如果你決定使用位域,你應該確保所有的位域聚集在一起;它會盡量減少浪費的空間。 [...]。在結構的上下文中,編譯器沒有自由移動位域。

..這涉及到完美的和諧與鏈接的答案,因爲編譯器將具有添加量少char gap_{i}[3];,當我們聚集了位域,從而最大限度地減少了STRUC的大小!


它值得嗎?

沒有那麼多恕我直言......:)

+0

爲什麼你把巨大的領域的OP沒有使相對差異似乎人爲地小? –

+0

@R ..只是爲了好玩。但行爲當然不會改變。檢查我的更新,你現在喜歡我的答案嗎? :) – gsamaras

+1

如果是24 vs 28(不添加愚蠢的花車),我會更喜歡它。 –

1

一般來說,是的。結構元素通常會以某種方式對齊(通常與元素的大小有時會更大),並且混合各種大小會導致大量填充。有辦法來緩解這一點。一般來說,如果將所有相同大小的元素分組在一起,則可能會打包而沒有任何填充。可以使用pragma強制一個結構被壓縮而沒有填充,但是這會導致對結構成員的非法訪問效率低下。

+1

您不能在位域上強制不填充。 –