第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如果字段順序不同,則結(jié)構(gòu)具有不同的大小

如果字段順序不同,則結(jié)構(gòu)具有不同的大小

Go
動漫人物 2021-11-29 15:50:41
package mainimport (    "fmt"    "unsafe")type A struct {    a bool    b int64    c int}type B struct {    b int64    a bool    c int}type C struct {}func main() {    // output 24    fmt.Println(unsafe.Sizeof(A{}))    // output 16    fmt.Println(unsafe.Sizeof(B{}))    // output 0    fmt.Println(unsafe.Sizeof(C{}))}結(jié)構(gòu)A和B具有相同的字段,但如果以不同的順序指定,它們會導(dǎo)致不同的大小。為什么?結(jié)構(gòu)體的大小C為零。系統(tǒng)為 分配了多少內(nèi)存a := C{}?謝謝。
查看完整描述

1 回答

?
PIPIONE

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超9個贊

1. 結(jié)構(gòu)尺寸

TL; 博士; (總結(jié)):如果您對字段重新排序,將使用不同的隱式填充,并且隱式填充計(jì)入struct.


請注意,結(jié)果取決于目標(biāo)架構(gòu);適用于您發(fā)布結(jié)果時GOARCH=386,但是當(dāng)GOARCH=amd64,既大小的A{}和B{}將是24個字節(jié)。


struct的字段地址必須對齊,type字段的地址int64必須是8字節(jié)的倍數(shù)。規(guī)格: 包裝unsafe:


計(jì)算機(jī)體系結(jié)構(gòu)可能需要對齊內(nèi)存地址;也就是說,對于一個變量的地址是一個因子的倍數(shù),變量的類型的對齊方式。該函數(shù)Alignof采用一個表示任何類型變量的表達(dá)式,并以字節(jié)為單位返回變量(的類型)的對齊方式。


對齊int64是8個字節(jié):


fmt.Println(unsafe.Alignof((int64(0)))) // Prints 8

因此,如果A因?yàn)榈谝粋€字段是bool,則后面有一個 7 字節(jié)的隱式填充,A.a因此A.b類型int64可以從 8 的倍數(shù)的地址開始。這(正是需要 7 字節(jié)填充)保證為在struct本身對準(zhǔn)這是8的倍數(shù)的地址,因?yàn)檫@是所有字段的最大尺寸。請參閱:規(guī)格:尺寸對齊保證:


對于xstruct 類型的變量:unsafe.Alignof(x)是 的unsafe.Alignof(x.f)每個字段f的所有值中的最大值x,但至少是1。


在這種情況下B(如果GOARCH=386是您的情況)在B.atype 字段之后只會有一個 3 字節(jié)的隱式填充,bool因?yàn)樵撟侄魏竺媸且粋€ type 字段int(大小為 4 個字節(jié))而不是int64.


對齊int是 4 個字節(jié) if GOARCH=386,和 8 個字節(jié) if GOARCH=amd64:


fmt.Println(unsafe.Alignof((int(0))))   // Prints 4 if GOARCH=386, and 8 if GOARCH=amd64

使用unsafe.Offsetof()找出領(lǐng)域的偏移量:


// output 24

a := A{}

fmt.Println(unsafe.Sizeof(a),

    unsafe.Offsetof(a.a), unsafe.Offsetof(a.b), unsafe.Offsetof(a.c))


// output 16

b := B{}

fmt.Println(unsafe.Sizeof(b),

    unsafe.Offsetof(b.b), unsafe.Offsetof(b.a), unsafe.Offsetof(b.c))


// output 0

fmt.Println(unsafe.Sizeof(C{}))


var i int

fmt.Println(unsafe.Sizeof(i))

輸出 if GOARCH=386(在Go Playground上嘗試):


24 0 8 16

16 0 8 12

0

4

輸出如果GOARCH=amd64:


24 0 8 16

24 0 8 16

0

8

2. 零尺寸值

規(guī)格:尺寸對齊保證:


如果結(jié)構(gòu)或數(shù)組類型不包含大小大于零的字段(或元素),則其大小為零。兩個不同的零大小變量可能在內(nèi)存中具有相同的地址。


所以規(guī)范只是提示使用相同的內(nèi)存地址,但這不是必需的。但是當(dāng)前的實(shí)現(xiàn)遵循它。也就是說,不會為大小為零的類型值分配內(nèi)存,這包括空結(jié)構(gòu)struct{}和零長度的數(shù)組,例如[0]int,或元素大小為零(并且具有任意長度)的數(shù)組。


看這個例子:


a := struct{}{}

b := struct{}{}

c := [0]int{}

d := [3]struct{}{}


fmt.Printf("%p %p %p %p %p", &a, &b, &c, &d, &d[2])

輸出(在Go Playground上嘗試):所有地址都相同。


0x21cd7c 0x21cd7c 0x21cd7c 0x21cd7c 0x21cd7c

有關(guān)有趣且相關(guān)的主題,請閱讀:Dave Cheney:Padding is hard


查看完整回答
反對 回復(fù) 2021-11-29
  • 1 回答
  • 0 關(guān)注
  • 182 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號