VC++中內(nèi)存對(duì)齊實(shí)例教程
內(nèi)存對(duì)其是VC++程序設(shè)計(jì)中一個(gè)非常重要的技巧,本文即以實(shí)例講述VC++實(shí)現(xiàn)內(nèi)存對(duì)其的方法。具體分析如下:
一、概述
我們經(jīng)??吹角?sizeof(A) 的值的問(wèn)題,其中A是一個(gè)結(jié)構(gòu)體,類,或者聯(lián)合體。
為了優(yōu)化CPU訪問(wèn)和優(yōu)化內(nèi)存,減少內(nèi)存碎片,編譯器對(duì)內(nèi)存對(duì)齊制定了一些規(guī)則。但是,不同的編譯器可能有不同的實(shí)現(xiàn),本文只針對(duì)VC++編譯器,這里使用的IDE是VS2012。
#pragma pack()是一個(gè)預(yù)處理,表示內(nèi)存對(duì)齊。布局控制#pragma,為編譯程序提供非常規(guī)的控制流信息。
二、結(jié)構(gòu)體的大小的規(guī)則
結(jié)構(gòu)體大小是處理器位數(shù)和結(jié)構(gòu)體內(nèi)最長(zhǎng)數(shù)據(jù)元素所占字節(jié)數(shù)二者中較小的那一個(gè)的整數(shù)倍。
比如說(shuō),假設(shè)處理器位數(shù)為n,結(jié)構(gòu)體內(nèi)最大數(shù)據(jù)元素所占字節(jié)數(shù)為m。
處理器為32位,n = 4;結(jié)構(gòu)體內(nèi)最大數(shù)據(jù)類型為short,m = 2; n > m;結(jié)構(gòu)體大小為m的整數(shù)倍,反之亦然。
注意:有些雖然是64位的操作系統(tǒng),但是編譯器卻是32位的,此時(shí)位數(shù)為32.
class A{ int a; char b; short c; }; sizeof(A)為8,為4的整數(shù)倍。 struct B{ short a; short b; short c; };
sizeof(B)為6,為2(sizeof(short))的整數(shù)倍。
注意:C++中的結(jié)構(gòu)體與類只有一個(gè)區(qū)別,就是結(jié)構(gòu)體成員默認(rèn)是public,而類默認(rèn)是private。
class X{ public: double a; float b; int c; char d; };
sizeof(X)為20,為4(處理器位數(shù))的整數(shù)倍。
三、#pragma pack(n)
#pragma pack(n)中的n默認(rèn)是4,即處理器位數(shù)32,但我們可以自己定義它的大小。
#pragma pack(1) class A{ public: int a; char b; short c; };
此時(shí)sizeof(A)為7,為1(#pragma pack(1))的整數(shù)倍。
#pragma pack(1) class X{ public: double a; int b; short c; char d; };
sizeof(X)為15,為1(#pragma pack(1))的整數(shù)倍。
#pragma pack(4) class X{ public: double a; int b; short c; char d; };
sizeof(X)為16,為4(#pragma pack(4))的整數(shù)倍。
#pragma pack(8) class X{ public: double a; int b; short c; char d; };
sizeof(X)為16,為8(#pragma pack(8) 或者 sizeof(double))的整數(shù)倍。
四、內(nèi)存對(duì)齊
結(jié)構(gòu)體中數(shù)據(jù)元素所在內(nèi)存地址由兩個(gè)因素決定。
一是#pragma pack(n) 中的n,二是元素類型所占字節(jié)數(shù),sizeof(type),兩者中取較小的一個(gè),元素內(nèi)存地址到結(jié)構(gòu)體或類的起始地址的偏移量為較小數(shù)的整數(shù)倍。
比如#pragma pack(n)默認(rèn)為4,有以下結(jié)構(gòu)體
struct A{ int a; char b; short c; };
a的起始地址距離結(jié)構(gòu)體起始地址的偏移量為0,是sizeof(int)的整數(shù)倍。
b的起始地址距離結(jié)構(gòu)體起始地址的偏移量為4,是sizeof(char)的整數(shù)倍。
c的起始地址距離結(jié)構(gòu)體起始地址的偏移量為5,不是sizeof(short)的整數(shù)倍,所以它的起始地址偏移量將會(huì)是6,而不是5。
輸出a, b, c 的地址為
0043FD68
0043FD6C
0043FD6E
可以看到c的起始地址比b的起始地址大了2個(gè)字節(jié),b占了2個(gè)字節(jié)的大小,這是因?yàn)閏的類型是short型,大小為2,而n默認(rèn)是4,sizeof(short) < n,所以偏移量應(yīng)該是2的整數(shù)倍,這里是6.
希望本文所述對(duì)大家的VC++程序設(shè)計(jì)有所幫助。
相關(guān)文章
C/C++讀取大文件數(shù)據(jù)方式詳細(xì)講解
這篇文章主要介紹了C語(yǔ)言/C++讀取大文件數(shù)據(jù)的完整方式過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09C語(yǔ)言雙指針多方法旋轉(zhuǎn)數(shù)組解題LeetCode
這篇文章主要為大家介紹了C語(yǔ)言雙指針使用多方法旋轉(zhuǎn)數(shù)組題解LeetCode,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02C++設(shè)計(jì)模式之建造者模式(Builder)
這篇文章主要介紹了C++設(shè)計(jì)模式之建造者模式Builder的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03C++獲取多瀏覽器上網(wǎng)歷史記錄示例代碼(支持獲取IE/Chrome/FireFox)
這篇文章主要介紹了C++獲取多瀏覽器上網(wǎng)歷史記錄示例代碼,支持獲取IE, Chrome,FireFox等瀏覽器2013-11-11C++ 數(shù)據(jù)類型強(qiáng)制轉(zhuǎn)化的實(shí)現(xiàn)
這篇文章主要介紹了C++ 數(shù)據(jù)類型強(qiáng)制轉(zhuǎn)化的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02c++ 如何在libuv中實(shí)現(xiàn)tcp服務(wù)器
這篇文章主要介紹了c++ 如何在libuv中實(shí)現(xiàn)tcp服務(wù)器,幫助大家更好的理解和使用libuv,感興趣的朋友可以了解下2021-02-02基于Matlab實(shí)現(xiàn)人工神經(jīng)網(wǎng)絡(luò)(ANN)回歸的示例詳解
這篇文章主要為大家詳細(xì)介紹了Matlab實(shí)現(xiàn)人工神經(jīng)網(wǎng)絡(luò)(ANN)回歸的相關(guān)資料,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-02-02