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

  C++博客 :: 首頁 :: 聯系 ::  :: 管理
  163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

常用鏈接

留言簿(48)

我參與的團隊

搜索

  •  

積分與排名

  • 積分 - 402524
  • 排名 - 59

最新評論

閱讀排行榜

評論排行榜

字節對齊指的是定義一個變量(包括常量,以下出現的變量不再特別說明)時,該變量在計算機內存區域的起始地址按照多少的倍數來存放。比如按4對齊, 則起始地址必須是4的倍數。字節對齊影響著計算機指令系統層讀寫變量的速度。這一點在計算機體系結構和匯編語言的書里面一般都有較詳細的說明,在此不多作 描述。主要總結一下編程時字節對齊的設置。

  C++提供了指令來設置對齊方式。一個是pack pragma,該指令用來設置結構成員的對齊;另一個是align,用來設置整個類型的對齊。下面我們看一下這兩個指令是如何影響變量在內存的存儲的。

1、pack pragma

pack pragma設置了struct、union或class中各成員的對齊方式,結構成員對齊指的是成員相對于起始地址的偏移量。該指令基本用法如下:
#pragma pack(n)
它 指定了結構成員按n(1,2,4,8,16)字節對齊,如果未指定n,則恢復成默認值。需要注意的是,它并不是指結構體中的每個成員都要按n對齊,而是按 照每個成員的大小和n相比較小的值對齊。下面引用MSDN中C++ Preprocessor Reference部分關于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的對齊值 align of member = min( pack setting value, sizeof(member) )

請看下面示例代碼:

#include <iostream>
using namespace std;

#pragma pack(show) //顯示當前結構成員對齊設置

#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;
}

筆者的測試環境為x86體系32位計算機 win2000操作系統,VS2003編譯器。
編譯器默認的成員對齊值是8字節,通過#pragma pack(show)指令,編譯的時候在輸出欄會限制默認對齊值。以上程序運行完通過調試的內存察看功能得到a和b的內存存儲區域如下:
a的存儲區域:0x0012FED0  02 00 00 00 31 00 03 00
b的存儲區域:0x0012FEBC  31 00 00 00 02 00 00 00 03 00 00 00
最前面的4字節整數是變量的起始地址,后面是變量的整個存儲區域。

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

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

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

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

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

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

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

這時有人可能要問,b為什么最后多了兩個字節00 00呢?這就是我們下面要講的,整個結構體的對齊。

2、align指令

align指令可以用于設置各種內置類型、自定義類型如struct、union或class的的對齊方式。指令格式為: __declspec(align( # )) ,#是對齊值,取值為2的1次方至2的8192次方。在聲明自定義類型或內置變量時,如果指定了對齊值,則對應變量的起始地址必須是該值的整數倍。除此外,它還會影響結構體的大小。下面引用兩段MSDN關于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).

從這段可以看出,如果沒有設置align(#)值,變量x按照sizeof(x)來對齊起始地址。類或結構體內的成員在類或結構體內部按照min( pack setting value,sizeof(member))來對齊。這個我們在pack指令部分已經分析過。

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(#)指令會影響結構體或類的大小??偨Y公式為:
sizeof(structure) = (結構體最后一個成員的偏移 + sizeof(結構體最后一個成員) ) 上取整 ( n* max( 結構體各成員的對齊值,align(#)設置的值 ) ); 其中n為正整數 。

根據該公式我們分析一下b為什么后面會多兩個填充字節0。
b的最后一個成s偏移為8,大小為2,b中各成員對齊值最大的為4,因為未設置align(#),所以上取整的數值為4n。8+2按4的倍數上取整為12。因此后面需要填充兩個字節,這樣才能使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;
}

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

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) 評論(2)  編輯 收藏 引用 所屬分類: C++

Feedback

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

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

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            午夜一级久久| 久久久蜜桃精品| 国产一区二区| 国产精品久久久久久亚洲调教| 欧美成人免费观看| 欧美成人r级一区二区三区| 一本久久综合| 女生裸体视频一区二区三区| 久久精品成人一区二区三区| 欧美在线二区| 久久精品一区二区三区不卡| 久久久久国内| 欧美激情一区在线| 国产精品久久久久一区二区三区共 | 亚洲裸体视频| 亚洲夫妻自拍| 亚洲精品美女免费| 日韩网站在线观看| 欧美在线视频全部完| 欧美成人首页| 亚洲五月婷婷| 蜜臀久久99精品久久久久久9| 欧美精品在线观看91| 国产欧美日韩一区二区三区| 91久久精品一区二区别| 亚洲综合三区| 欧美插天视频在线播放| 一区二区三区日韩欧美| 欧美专区在线| 国产精品wwwwww| 国产一区二区黄| 亚洲一级影院| 亚洲福利电影| 久久精品123| 国产精品国产三级国产普通话99 | 欧美日韩精品不卡| 国产三级欧美三级| 亚洲无线一线二线三线区别av| 久久久久国内| 亚洲色图自拍| 欧美精品色网| 亚洲区免费影片| 久久久久久久精| 亚洲午夜在线视频| 欧美激情第二页| 尤物在线精品| 久久精品九九| 亚洲欧美日韩国产一区二区| 欧美午夜视频一区二区| 亚洲人成在线播放| 农村妇女精品| 久久久久国色av免费观看性色| 国产精品亚洲一区| 亚洲一区二区高清视频| 亚洲精品美女久久7777777| 久久精品视频播放| 国内精品国产成人| 久久久久成人精品免费播放动漫| 亚洲一区综合| 国产伦精品一区二区三区视频孕妇| 亚洲美女黄色| 亚洲精品中文在线| 欧美激情1区2区| 欧美精品一区在线播放| 最新成人av网站| 欧美福利小视频| 久久天天综合| 最新国产精品拍自在线播放| 欧美黄色免费| 欧美日韩成人综合天天影院| 亚洲视频一区在线| 亚洲一区二区三区涩| 国产欧美精品| 久久久久久综合| 久久精品综合一区| 亚洲国产一成人久久精品| 亚洲国产成人不卡| 亚洲人成人一区二区三区| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美激情第二页| 欧美岛国在线观看| 亚洲精品久久久久久久久久久| 亚洲欧洲日本在线| 欧美午夜在线观看| 国语精品中文字幕| 蜜桃精品久久久久久久免费影院| 久久久蜜桃一区二区人| 亚洲精品久久久久久久久久久| 亚洲人成在线播放| 国产精品视频在线观看| 久久综合久色欧美综合狠狠| 久久这里只有| 亚洲天堂网在线观看| 亚洲私人黄色宅男| 好看不卡的中文字幕| 亚洲人成在线播放网站岛国| 国产精品一卡| 欧美激情视频一区二区三区免费| 欧美人妖另类| 久久女同互慰一区二区三区| 欧美国产日本高清在线| 午夜精品一区二区三区在线视| 亚洲电影av在线| 欧美视频一区二区三区…| 亚洲精品黄色| 性感少妇一区| 快播亚洲色图| 在线日韩中文| 欧美精品粉嫩高潮一区二区 | 欧美一区二区三区四区在线| 欧美专区第一页| 亚洲一区二区三区视频| 久久精品综合| 亚洲欧美bt| 欧美激情一区二区三区全黄| 欧美中日韩免费视频| 欧美—级在线免费片| 猛男gaygay欧美视频| 国产农村妇女毛片精品久久麻豆 | 欧美国产精品v| 欧美噜噜久久久xxx| 欧美在线亚洲一区| 欧美精品尤物在线| 老色鬼久久亚洲一区二区| 欧美偷拍另类| 亚洲精品九九| 亚洲精品免费一二三区| 久久久久成人精品| 久久久久久久一区二区三区| 亚洲一二三四久久| 久久国产天堂福利天堂| 亚洲国产黄色片| 亚洲一区免费视频| 国产欧美日韩不卡| 亚洲一区中文| 欧美在线高清| 国产视频精品xxxx| 亚洲免费影视第一页| 性久久久久久久久久久久| 欧美特黄a级高清免费大片a级| 亚洲人成绝费网站色www| aaa亚洲精品一二三区| 欧美精品福利| 亚洲私人影院在线观看| 欧美亚洲专区| 激情国产一区| 另类专区欧美制服同性| 亚洲大胆在线| 一区二区三区精品久久久| 欧美日韩精品一本二本三本| 99re热这里只有精品视频| 亚洲视频免费在线| 欧美婷婷六月丁香综合色| 一本色道久久综合亚洲精品婷婷 | 亚洲黄网站黄| 亚洲图片欧洲图片日韩av| 国产精品欧美精品| 亚洲一区二区视频在线| 午夜久久99| 午夜精品美女自拍福到在线 | 亚洲综合欧美| 国产专区欧美精品| 欧美chengren| 一区二区91| 久久最新视频| 一本色道久久综合亚洲精品按摩 | 久久一区精品| 日韩一级黄色av| 久久不射中文字幕| 永久免费精品影视网站| 欧美激情免费在线| 午夜日韩在线观看| 亚洲国产日韩在线| 午夜激情综合网| 在线不卡a资源高清| 欧美精品一区二区三区视频| 亚洲在线视频网站| 亚洲第一天堂无码专区| 午夜国产欧美理论在线播放| 精品二区视频| 国产精品女主播| 欧美精品一区二| 性欧美办公室18xxxxhd| 亚洲精品国产精品国自产在线| 欧美与欧洲交xxxx免费观看| 亚洲美女色禁图| 黑人巨大精品欧美黑白配亚洲| 欧美日韩在线精品| 麻豆精品在线观看| 欧美中文字幕在线播放| 日韩亚洲精品在线| 欧美成人a视频| 久久国内精品自在自线400部| 日韩写真在线| 亚洲国产三级在线| 一区二区在线看| 国产日韩在线看片| 国产精品日本| 欧美亚日韩国产aⅴ精品中极品| 欧美成年人在线观看|