青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

  C++博客 :: 首頁 :: 聯(lián)系 ::  :: 管理
  163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

常用鏈接

留言簿(48)

我參與的團(tuán)隊(duì)

搜索

  •  

積分與排名

  • 積分 - 402521
  • 排名 - 59

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

字節(jié)對(duì)齊指的是定義一個(gè)變量(包括常量,以下出現(xiàn)的變量不再特別說明)時(shí),該變量在計(jì)算機(jī)內(nèi)存區(qū)域的起始地址按照多少的倍數(shù)來存放。比如按4對(duì)齊, 則起始地址必須是4的倍數(shù)。字節(jié)對(duì)齊影響著計(jì)算機(jī)指令系統(tǒng)層讀寫變量的速度。這一點(diǎn)在計(jì)算機(jī)體系結(jié)構(gòu)和匯編語言的書里面一般都有較詳細(xì)的說明,在此不多作 描述。主要總結(jié)一下編程時(shí)字節(jié)對(duì)齊的設(shè)置。

  C++提供了指令來設(shè)置對(duì)齊方式。一個(gè)是pack pragma,該指令用來設(shè)置結(jié)構(gòu)成員的對(duì)齊;另一個(gè)是align,用來設(shè)置整個(gè)類型的對(duì)齊。下面我們看一下這兩個(gè)指令是如何影響變量在內(nèi)存的存儲(chǔ)的。

1、pack pragma

pack pragma設(shè)置了struct、union或class中各成員的對(duì)齊方式,結(jié)構(gòu)成員對(duì)齊指的是成員相對(duì)于起始地址的偏移量。該指令基本用法如下:
#pragma pack(n)
它 指定了結(jié)構(gòu)成員按n(1,2,4,8,16)字節(jié)對(duì)齊,如果未指定n,則恢復(fù)成默認(rèn)值。需要注意的是,它并不是指結(jié)構(gòu)體中的每個(gè)成員都要按n對(duì)齊,而是按 照每個(gè)成員的大小和n相比較小的值對(duì)齊。下面引用MSDN中C++ Preprocessor Reference部分關(guān)于pack指令的說明:

n (optional)
    Specifies the value, in bytes, to be used for packing. The default value for n is 8. Valid values are 1, 2, 4, 8, and 16. The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.

即成員member的對(duì)齊值 align of member = min( pack setting value, sizeof(member) )

請(qǐng)看下面示例代碼:

#include <iostream>
using namespace std;

#pragma pack(show) //顯示當(dāng)前結(jié)構(gòu)成員對(duì)齊設(shè)置

#pragma pack(8)
struct A
...{
    int n;
    char c;
    short s;
};
struct B
...{
    char c;
    int n;
    short s;
};
#pragma pack()

int _tmain(int argc, _TCHAR* argv[])
...{
    A a;
    B b;

    memset( &a, 0, sizeof(A) );
    memset( &b, 0, sizeof(B) );

    a.c = '1';
    a.n = 2;
    a.s = 3;

    b.c = '1';
    b.n = 2;
    b.s = 3;

    cout << sizeof(A) << endl;
    cout << sizeof(B) << endl;

    return 0;
}

筆者的測(cè)試環(huán)境為x86體系32位計(jì)算機(jī) win2000操作系統(tǒng),VS2003編譯器。
編譯器默認(rèn)的成員對(duì)齊值是8字節(jié),通過#pragma pack(show)指令,編譯的時(shí)候在輸出欄會(huì)限制默認(rèn)對(duì)齊值。以上程序運(yùn)行完通過調(diào)試的內(nèi)存察看功能得到a和b的內(nèi)存存儲(chǔ)區(qū)域如下:
a的存儲(chǔ)區(qū)域:0x0012FED0  02 00 00 00 31 00 03 00
b的存儲(chǔ)區(qū)域:0x0012FEBC  31 00 00 00 02 00 00 00 03 00 00 00
最前面的4字節(jié)整數(shù)是變量的起始地址,后面是變量的整個(gè)存儲(chǔ)區(qū)域。

現(xiàn)在我們按照 align of member = min( pack setting value, sizeof(member) )的公式分析一下a和b的存儲(chǔ)。

a 的第一個(gè)成員n為int,大小為4,align of a.n = min(8,sizeof(int) ),對(duì)齊值為4。第一個(gè)成員相對(duì)于結(jié)構(gòu)體起始地址從0偏移開始,前四個(gè)字節(jié)02 00 00 00即為n的存儲(chǔ)區(qū)域,因?yàn)閤86是Little Endian(低字節(jié)在前)的字節(jié)順序,所以第一字節(jié)是2,后面三個(gè)字節(jié)0,我們通常寫成0x00000002;

a的第二個(gè)成員c為char,大小為1,align of a.c=min(8,sizeof(char)),對(duì)齊值為1。c緊接著a后面存儲(chǔ)從偏移4開始,滿足1字節(jié)對(duì)齊的要求。它的值為'1',ASCII碼為0x31,共一個(gè)字節(jié)31;

a的第三個(gè)成員為short,大小為2,align of a.s=min(8,sizeof(short)),對(duì)齊值為2。如果緊接第二個(gè)成員從偏移5開始存儲(chǔ)就不滿足2字節(jié)對(duì)齊,因此跳過1個(gè)字節(jié),從偏移6字節(jié)的地方開始存儲(chǔ),即最后兩個(gè)字節(jié)03 00;

b的第一個(gè)成員c為char,大小為1,align of a.c=min(8,sizeof(char)),對(duì)齊值為1。第一個(gè)成員從偏移起始地址0字節(jié)開始存儲(chǔ),它的值為'1',ASCII碼為0x31,共一個(gè)字節(jié)31;

b 的第二個(gè)成員n為int,大小為4,align of a.n = min(8,sizeof(int) ),對(duì)齊值為4。如果緊接第二個(gè)成員后面從偏移1開始存儲(chǔ)就不能4字節(jié)對(duì)齊,因此跳過3個(gè)字節(jié),從偏移4字節(jié)的地方開始存儲(chǔ),即第5-8的四個(gè)字節(jié)02 00 00 00;

b的第三個(gè)成員為short,大小為2,align of a.s=min(8,sizeof(short)),對(duì)齊值為2。緊接第二個(gè)成員從偏移8字節(jié)的地方開始存儲(chǔ),即9-10兩個(gè)字節(jié)03 00;

這時(shí)有人可能要問,b為什么最后多了兩個(gè)字節(jié)00 00呢?這就是我們下面要講的,整個(gè)結(jié)構(gòu)體的對(duì)齊。

2、align指令

align指令可以用于設(shè)置各種內(nèi)置類型、自定義類型如struct、union或class的的對(duì)齊方式。指令格式為: __declspec(align( # )) ,#是對(duì)齊值,取值為2的1次方至2的8192次方。在聲明自定義類型或內(nèi)置變量時(shí),如果指定了對(duì)齊值,則對(duì)應(yīng)變量的起始地址必須是該值的整數(shù)倍。除此外,它還會(huì)影響結(jié)構(gòu)體的大小。下面引用兩段MSDN關(guān)于align的描述:

Without __declspec(align( # )) , Visual C++ aligns data on natural boundaries based on the size of the data, for example 4-byte integers on 4-byte boundaries and 8-byte doubles on 8-byte boundaries. Data in classes or structures is aligned within the class or structure at the minimum of its natural alignment and the current packing setting (from #pragma pack or the /Zp compiler option).

從這段可以看出,如果沒有設(shè)置align(#)值,變量x按照sizeof(x)來對(duì)齊起始地址。類或結(jié)構(gòu)體內(nèi)的成員在類或結(jié)構(gòu)體內(nèi)部按照min( pack setting value,sizeof(member))來對(duì)齊。這個(gè)我們?cè)趐ack指令部分已經(jīng)分析過。

The sizeof value for any structure is the offset of the final member, plus that member's size, rounded up to the nearest multiple of the largest member alignment value or the whole structure alignment value, whichever is greater.

從這段可以看出,align(#)指令會(huì)影響結(jié)構(gòu)體或類的大小。總結(jié)公式為:
sizeof(structure) = (結(jié)構(gòu)體最后一個(gè)成員的偏移 + sizeof(結(jié)構(gòu)體最后一個(gè)成員) ) 上取整 ( n* max( 結(jié)構(gòu)體各成員的對(duì)齊值,align(#)設(shè)置的值 ) ); 其中n為正整數(shù)

根據(jù)該公式我們分析一下b為什么后面會(huì)多兩個(gè)填充字節(jié)0。
b的最后一個(gè)成s偏移為8,大小為2,b中各成員對(duì)齊值最大的為4,因?yàn)槲丛O(shè)置align(#),所以上取整的數(shù)值為4n。8+2按4的倍數(shù)上取整為12。因此后面需要填充兩個(gè)字節(jié),這樣才能使sizeof(b) == 12。

下面以一代碼來說明align(#)指令的用法:

#include <iostream>
using namespace std;

#define CACHE_LINE  32
#define CACHE_ALIGN __declspec(align(CACHE_LINE))

#pragma pack(8)

struct CACHE_ALIGN S1  
...{
   int a, b, c, d;
};

struct S3
...{
   struct S1 s1;                   
   int a;        
};
#pragma pack()

int _tmain(int argc, _TCHAR* argv[])
...{
    CACHE_ALIGN int i = 2;

    cout << sizeof(S1) << endl;
    cout << sizeof(S3) << endl;

    return 0;
}

運(yùn)行程序輸出32和64,按公式sizeof(structure) = (結(jié)構(gòu)體最后一個(gè)成員的偏移 + sizeof(結(jié)構(gòu)體最后一個(gè)成員) ) 上取整 ( n* max( 結(jié)構(gòu)體各成員的對(duì)齊值,align(#)設(shè)置的值 ) )分析:

sizeof(S1) = (12+4) 上取整 ( n * max( 4, 32 ) )
sizeof(S1) = (16) 上取整 ( 32  )
sizeof(S1) = 32

S3的大小留待大家練練手。


posted on 2007-12-23 20:04 sdfasdf 閱讀(1226) 評(píng)論(2)  編輯 收藏 引用 所屬分類: C++

Feedback

# re: 關(guān)于pragma pack的用法(五)別嫌我啰嗦! 2007-12-23 21:01 mengxin
ding  回復(fù)  更多評(píng)論
  

# re: 關(guān)于pragma pack的用法(五)別嫌我啰嗦! 2007-12-23 21:01 sail
謝謝老兄  回復(fù)  更多評(píng)論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            午夜精品久久久久影视| 久久亚洲国产精品一区二区| 亚洲欧美成人一区二区在线电影| 国产欧美日韩一区二区三区在线观看 | 欧美成年视频| 免费在线看成人av| 亚洲午夜国产成人av电影男同| 亚洲国产精品精华液2区45| 久久精品综合网| 久久九九久精品国产免费直播| 91久久精品一区二区三区| 亚洲国产mv| 日韩一级裸体免费视频| 99热在线精品观看| 亚洲视频一二三| 亚洲一区欧美激情| 亚洲精品综合精品自拍| 国内精品久久久久影院优| 国产伊人精品| 亚洲国产经典视频| 99v久久综合狠狠综合久久| 日韩亚洲不卡在线| 亚洲免费伊人电影在线观看av| 久久激情婷婷| 韩日在线一区| 玉米视频成人免费看| 在线欧美日韩| 日韩亚洲欧美成人| 午夜精品亚洲一区二区三区嫩草| 亚洲精品在线一区二区| 亚洲成色999久久网站| 最新国产成人在线观看 | 国产欧美一区二区精品婷婷| 国产综合色产| 狠狠色综合色综合网络| 亚洲丶国产丶欧美一区二区三区| 亚洲精美视频| 亚洲欧美另类在线观看| 一本色道久久加勒比88综合| 欧美一级午夜免费电影| 欧美一区二区三区男人的天堂| 麻豆精品一区二区av白丝在线| 亚洲精品男同| 久久激情一区| 欧美激情乱人伦| 国产乱码精品一区二区三区忘忧草 | 欧美精品乱码久久久久久按摩| 欧美三级电影精品| 伊人久久婷婷色综合98网| 亚洲国产一区二区三区高清| 亚洲永久免费观看| 欧美a一区二区| 亚洲男女自偷自拍图片另类| 欧美国产一区在线| 国产自产女人91一区在线观看| 一区二区日韩伦理片| 美女视频网站黄色亚洲| 亚洲激情成人| 久久综合九色99| 欧美激情第10页| 一区免费观看| 亚洲四色影视在线观看| 欧美激情一区二区三区蜜桃视频 | 久久久www成人免费无遮挡大片| 欧美日韩精品欧美日韩精品一| 激情久久影院| 亚洲校园激情| 亚洲激情精品| 欧美国产日本| 久久国产精品网站| 国产日韩欧美夫妻视频在线观看| 亚洲午夜伦理| 一本久久青青| 欧美午夜精品久久久久久人妖| 亚洲精品一区二区网址| 亚洲精品护士| 免费观看国产成人| 欧美黄色免费| 久久精品视频va| 国产一区二区三区久久悠悠色av| 中文欧美在线视频| 亚洲激情成人网| 欧美精品久久久久久久免费观看| 亚洲激情av在线| 亚洲激情成人网| 欧美日本国产精品| 亚洲免费高清| 欧美mv日韩mv亚洲| 麻豆av一区二区三区久久| 亚洲国产欧美在线人成| 欧美激情一区二区三区成人 | 久久精品一区二区| 黄色成人免费网站| 欧美成人亚洲成人日韩成人| 久久综合久久综合久久| 国产在线精品二区| 亚洲欧洲精品一区二区| 欧美激情五月| 欧美色综合天天久久综合精品| 日韩视频免费大全中文字幕| 日韩午夜精品视频| 国产精品亚洲不卡a| 欧美一区二区三区视频免费播放| 午夜在线电影亚洲一区| 久久婷婷国产综合国色天香| 久久成人免费电影| 国产真实精品久久二三区| 在线一区二区日韩| 午夜精品久久久久久久99热浪潮| 欧美高清视频www夜色资源网| 欧美不卡激情三级在线观看| 久久综合九色综合网站| 免费在线日韩av| 亚洲欧美国内爽妇网| 快she精品国产999| 午夜精品久久久久久久蜜桃app| 久久婷婷人人澡人人喊人人爽 | 亚洲精品无人区| 欧美有码视频| 亚洲主播在线| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美一级午夜免费电影| 亚洲视频日本| 欧美高清日韩| 99精品国产一区二区青青牛奶| 久久久久国产成人精品亚洲午夜| 国产精品五月天| 美女国产一区| 小黄鸭精品aⅴ导航网站入口| 久久久夜夜夜| 欧美一区二视频在线免费观看| 激情综合激情| 国产精品国产三级国产专区53| 亚洲精品一二三| 久久精品免费播放| 国产午夜一区二区三区| 免费国产一区二区| 亚洲人成网站精品片在线观看 | 中文在线一区| 亚洲自拍偷拍视频| 亚洲二区三区四区| 久久久久久久久久看片| 欧美一区二区三区免费大片| 欧美一区二区三区电影在线观看| 亚洲第一福利在线观看| 国产视频亚洲精品| 亚洲一区二区三区视频播放| 亚洲性感激情| 国产精品高清一区二区三区| 亚洲女同在线| 久久国产主播| 亚洲国产精品成人一区二区| 免费在线观看一区二区| 亚洲国产精品一区| 日韩一级视频免费观看在线| 欧美高清视频一区二区三区在线观看 | 久久激情五月婷婷| 免费黄网站欧美| 亚洲精品欧美日韩| 欧美日韩在线观看一区二区| 亚洲一区精品在线| 久久久精品网| 亚洲美女视频| 国产精品一区视频网站| 久久久国产精彩视频美女艺术照福利| 免费一区二区三区| 一区二区三欧美| 国产欧美一区二区精品仙草咪| 久久综合成人精品亚洲另类欧美| 亚洲风情亚aⅴ在线发布| 在线视频亚洲| 国产精品午夜在线| 久久女同互慰一区二区三区| 亚洲大胆人体在线| 亚洲精品国产日韩| 欧美日韩国产一区二区三区地区 | 免费久久99精品国产| 国产精品入口| 最新成人在线| 欧美一区二区三区久久精品| 亚洲精品久久久蜜桃| 日韩一级黄色大片| 蜜桃久久av| 99re视频这里只有精品| 亚洲一级一区| 欧美黄色大片网站| 亚洲人成欧美中文字幕| 欧美制服丝袜| 精品999久久久| 久久免费黄色| 亚洲免费精彩视频| 欧美h视频在线| 一本久久综合| 国产精品国产三级国产普通话蜜臀| 亚洲欧美国产另类| 亚洲欧洲在线观看| 欧美一区二区视频免费观看| 亚洲国产精品久久91精品| 欧美激情日韩| 久久手机精品视频|