国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
簡要記錄sizeof和內(nèi)存對齊
今天有人在某QQ群中問下面這個結(jié)構(gòu)體有多大:
#pragma pack(4)struct STV{	char a;	short int b;	char c;};

當(dāng)時我第一反應(yīng)是12,不過又總覺得有點(diǎn)不對勁,還是寫了段代碼測試下,發(fā)現(xiàn)結(jié)果居然是6.

嗯?6,難道編譯器沒看到這句話么:#pragma pack(4)?

但是當(dāng)我把結(jié)構(gòu)體的定義修改為

#pragma pack(1)struct STV{	char a;	short int b;	char c;};

后,結(jié)果又變成了4,那么#pragma pack是在起作用的。然后又試著改為#pragma pack(8)和#pragma pack(16),結(jié)果還是6.

心中大概有點(diǎn)明白為什么了。

google之,原來對于#pragma pack的處理方式是這樣進(jìn)行的:

當(dāng)結(jié)構(gòu)體中最長寬度的數(shù)據(jù)成員的寬度小于 n 時,按該成員寬度對齊;
當(dāng)最長寬度的數(shù)據(jù)成員的寬度大于或等于 n 時,按 n 對齊。

結(jié)構(gòu)體STV中成員寬度最大為2,所以當(dāng)n=4,8,16的時候還是按照寬度2來對齊的。

–EOF
 
 
 
 
 
    本來,一般是不自己計(jì)算sizeof的,知道內(nèi)存對齊會對sizeof有影響,所以從來不手算,而是代碼里寫上sizeof。今天又看到http://blog.vckbase.com/smileonce/archive/2005/08/08/10658.html,翻來了http://blog.vckbase.com/billdavid/archive/2004/06/23/509.html ,自己想想還是也記錄一下,萬一以后自己真的也要計(jì)算sizeof,忘了,還能有個提示,也給不是很明白的朋友一個參考。
struct sample1
{
    char a;        /// sizeof(char) = 1
    double b;    /// sizeof(double) = 8
};
///default(  缺省#pragam pack(8) ——VC6和VC71,其它編譯器,個人未知 )
    ///1+8 = 9 —> 16(  8 < 9 < 16  )

#pragma pack( 4 )
    ///1+8 = 9 —> 12(  8 < 9 < 12  )

#pragma pack( 2 )
    ///1+8 = 9 —> 10(  8 < 9 < 10  )

#pragma pack( 1 )
    ///1+8 = 9 —> 9

#pragma pack( 16 )
    ///1+8 = 9 —> 16(  16—>8 ---- 8 < 9 < 16  )

struct sample2
{
    char a;     ///1
    int b;        ///4
};
#pragma pack( 8 )
    /// 1 + 4  = 5 —> 8(  8 —> 4  )

#pragma pack( 16 )
    /// 1 + 4 = 5 —> 8( 16 —> 4  )

    說明:#pragma pack告訴編譯器進(jìn)行內(nèi)存邊界對齊,一般都是采用編譯器的設(shè)置對整個項(xiàng)目采用同一對齊方案,而且通常為缺省8字節(jié)對齊。



/////////////////////////////////以下內(nèi)容于 2005-12-10 添加/////////////////////////////////


    今天又看到以前測試的一段代碼,突然不明白了起來,又稍寫了幾個測試。
struct sample3
{
    char a;  ///1
    int b;    ///4
    char c;  ///1
};
///default                  ///12
#pragma pack( 4 )   ///12
#pragma pack( 2 )   ///08
#pragma pack( 1 )   ///06
#pragma pack( 16 ) ///12

    原來,其實(shí)編譯器,根據(jù)對齊指示的對齊字節(jié)和最大成員的字節(jié),對每個成員進(jìn)行了對齊:編譯器會取對齊指示和最大成員字節(jié)中較小的一個用于補(bǔ)齊其它成員。那么,上面的sample1/2/3也就都在情理之中了。為了證實(shí)這點(diǎn),我們還再看一個例子:
struct sample4
{
    char a;      ///1
    int b;         ///4
    double c;  ///8
    char d;      ///1
};
///default:                ///8+8+8+8 = 32
#pragma pack( 4 )   ///4+4+8+4 = 20
#pragma pack( 2 )   ///2+4+8+2 = 16
#pragma pack( 1 )   ///1+4+8+1 = 14
#pragma pack( 16 ) ///8+8+8+8 = 32
而實(shí)際上,編譯器給出的值是:24、20、16、14、24
那么說明我錯了。注意一下,我發(fā)現(xiàn)char a,int b加起來也才5<8,難到編譯器進(jìn)行了聯(lián)合對齊?
struct sample5
{
    char a;      ///1
    double c;  ///8
    int b;         ///4
    char d;      ///1
};
編譯器給出結(jié)果:24、20、16、14、24

    這用聯(lián)合對齊的解釋正好符合,我又試驗(yàn)了不同的數(shù)據(jù),發(fā)現(xiàn)這個結(jié)論并不太準(zhǔn)確確。于是,我輸出了每一個對象成員地址進(jìn)行分析。由于試驗(yàn)數(shù)據(jù)量很大,這里就不列出了。

最后得到了以下結(jié)論:
    1. 成員的對齊是按聲明順序進(jìn)行的;
    2. 對齊值由編譯指示和最大成員兩者較小的值決定;
    3. 未對齊到對齊值的成員一起形成塊對齊(聯(lián)合對齊);
    4. 上一個(下一個)對齊采用自己較大則不變,自己較小則填充自己對齊到上一個(下一個)大??;
    5. 每成員對齊:如果前面已對齊到對齊值,下一個對齊自己。如果前面未對齊到對齊值,如果加上下一個成員不大于對齊值,下一個對齊自己,否則填充自己塊對齊到對齊值。
    6. 最后還未對齊到對齊值的,填充空間塊對齊到對齊值。

從這些結(jié)論,可以得到:
    1. 以上的對齊原則其實(shí)是盡量整齊排列、盡量節(jié)省內(nèi)存。
    2. 聲明成員應(yīng)該盡量避免不同類型錯雜開來,最好采用從小到大或者從大到小的順序(錯開后,會因?yàn)樯蠈R和下對齊而增加填充開銷)。
    3. 編譯器缺省采用8字節(jié)對齊主要是因?yàn)樽畲蠡绢愋蜑?自己(以前自己不明白,在論壇提過問,后來,以為是SSE指令的原因)。
    4. 手算sizeof是沒有必要的,負(fù)責(zé)的(可以先對齊出對齊塊,用塊數(shù)乘對齊值)。

posted on 2005-08-09 21:14 終于有了間茅草棚 閱讀(14941) 評論(10)  編輯 收藏

評論

# re: 簡要記錄sizeof和內(nèi)存對齊

反正我是從來都是按照16字節(jié)對齊的,不夠的話使用 BYTE m_reserved[n];來湊齊
例如:
struct sample1
{
    char a;
    double b; 
    BYTE m_reserved[7];
};
2005-08-09 23:50 | hengai

# re: 簡要記錄sizeof和內(nèi)存對齊

只是描述一下怎么算。以及,告訴初學(xué)者,有填充。
這樣,在處理時有所優(yōu)化,比如:發(fā)送網(wǎng)絡(luò)數(shù)據(jù)時,發(fā)整個塊就不是很明智。
2005-08-10 22:03 | 清風(fēng)雨

# re: 簡要記錄sizeof和內(nèi)存對齊

怎么和panic說的不太一樣??

http://blog.vckbase.com/panic/archive/2005/04/02/4340.aspx
2005-08-11 08:56 | yuxuan

# re:yuxuan

是一樣的。 仔細(xì)研究一下就明白了。
2005-08-11 11:28 | 清風(fēng)雨

# re: 簡要記錄sizeof和內(nèi)存對齊

不錯,很詳細(xì),我也是剛知道不久的,慚愧慚愧。。。
2005-12-17 18:19 | edog

# 簡要記錄sizeof和內(nèi)存對齊 [TrackBack]

http://blog.vckbase.com/zhangjw_cn/archive/2005/08/09/10701.html
uvbs引用了該文章,地址:http://blog.csdn.net/UVBS/archive/2006/03/21/630971.aspx
2006-03-21 11:57 | uvbs

# 一些關(guān)于sizeof的例子[TrackBack]

轉(zhuǎn)自:http://zhengrongyang.spaces.live.com/blog/對幾組sizeof信息的分析對幾組sizeof信息的分析 對于很多C 新手而言,對象或變量的sizeof信息總是讓人捉摸不透,以下程序列舉了幾個典型的sizeof信息,希望能解答大家在使用sizeof時的疑問。
fengsanshao引用了該文章,地址:http://blog.csdn.net/fengsanshao/archive/2007/03/18/1533036.aspx
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
結(jié)構(gòu)體(含位域)的sizeof
也談內(nèi)存對齊 :: Tony Bai
親歷多家名企C語言面試題
C語言結(jié)構(gòu)體對齊問題
簡要講述C/C++中的操作符sizeof()
結(jié)構(gòu)體對齊問題.
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服