1. 程式人生 > >vs2012編譯器c++儲存記憶體對齊情況詳解

vs2012編譯器c++儲存記憶體對齊情況詳解

        為了方便資料的讀取,編譯器在資料儲存的時候會做一些資料優化,用空間來獲取時間,所以資料佔用的記憶體一般比較大,尤其是把sizeof用於結構體的時候,一般會得到不一樣的情況,這就是位元組對齊的情況。

       對齊大小的設定:

       預設情況下,筆者的電腦的預設對齊大小為8個位元組,我們可以通過在程式碼中新增#pragma pack(n)(n為要設定的對齊大小,windows下可以設定為1,2,4,8,16,linux中g++只能是1,2,4),通過#pragma pack(show)來通過警告的方式來顯示當前的對齊大小,#pragma pack(pop)來取消之前的設定。注意:當設定的對齊位數比結構體中最大的型別佔用的位元組數還要大時,將不會起作用,比如定義的結構體中最大的為int型,而我們把n設定為8時,編譯器依然以4位元組為對齊方式,而不會為8,所以設定對齊方式只有在比最長的位元組還小的情況下才起作用,當結構體中還有結構體的情況時,不是以結構體的結構體的大小為最大長度,而是依然找出結構體的普通變數和結構體的結構的一般變數為基準。

下面來看看測試的結果:(以結構體來測試)     

#pragma pack(8)
struct student
{
        char a;  //開始的偏移為0,而char的大小為1,小於8,所以要是1的倍數,滿足,所以當前佔用1位元組大小
	int b;   //當前的偏移為1,4<8,以4的倍數為基準,1+3+4=8個位元組
        double c; //因為8>=8,所以以8為基準,1+3+4+8=16
};


得到的結果為:

然後我把變數c和變數b的位置變換一下:

#pragma pack(8)
struct student
{
	char a;  //同上,大小為1
	double c; //8>=8,起始偏移必須為8的倍數,1+7+8=16
	int b;   //當前的偏移量為16,為4的倍數,所以直接加在後面:1+7+8+4=20,但總體必須是8的倍數,所以後面補齊,20+4=24
};
#pragma pack(show)
結果為:

上面的都是一些普通變數的對齊,如果是結構體中有結構體,情況有些許的不同:(現在把對齊方式改由8改為4)

#pragma pack(4)
struct teacher
{
	char a;  //1
	double c;//1+3+8=12
	int b;//1+3+8+4=16
};
struct student
{
	char a; //1
	double c;//1+3+8=12
	int b;//1+3+8+4=16
	char d;//16+1=17
	teacher e; //把17填充到4的倍數:20,20+16=36,為4的倍數了,直接輸出大小
	//char f; //此時輸出為40
};
#pragma pack(show)
得到的結果為:

補充:

class a
{
//public:
	int i;
	char c1;
};
class b:public a
{
//public:
	char c2;
};
class c:public b
{
//public:
	char c3;
};

void main()
{
	cout<<sizeof(a)<<endl;
	cout<<sizeof(b)<<endl;
	cout<<sizeof(c)<<endl;
}


如上所述,普通繼承時,當所有繼承都是公有繼承時:

1、在64位的g++上執行得到的結果為:8,8,8;因為在g++中普通繼承時,基類和派生類沒有記憶體間隔,所以對於a: 4+1+3=8; b:4+1+1+2=8, c: 4+1+1+1+1=8;

2、在vs2012中(64位作業系統)執行的結果為:8,12,16, 因為基類和派生類有記憶體間隔,所以a:4+1+3=8, b:4+1+3+1+3=12, c:4+1+3+1+3+1+3=16;

當把私有的成員函式改為共有的時候在g++編譯器下結果會有變化,而vs2012無變化:

1、g++中輸出的結果:8,12,12    

2、vs2012中輸出的結果如上;

相關推薦

vs2012編譯器c++儲存記憶體情況

        為了方便資料的讀取,編譯器在資料儲存的時候會做一些資料優化,用空間來獲取時間,所以資料佔用的記憶體一般比較大,尤其是把sizeof用於結構體的時候,一般會得到不一樣的情況,這就是位元組對齊的情況。        對齊大小的設定:        預設情況下,筆

C/C++結構體方式,從記憶體地址進行解析

注意:童鞋們如果仔仔細細看完這篇部落格,肯定能明白結構體的對齊方式。 最近在做一個專案的時候,客戶給的鐳射點雲檔案是二進位制形式,因此需要根據客戶定義的結構體,將點雲檔案儲存為文字檔案方便在第三方軟體如cloudCompare中檢視。但是發現客戶的結構體所佔記憶體空間跟我的

C語言位元組問題

部落格園 首頁 新隨筆 聯絡 管理 訂閱 隨筆- 80  文章- 0  評論- 125  引言      考慮下面的結構體定義: 1 typedef struct{ 2 char c1; 3 short s; 4

C++11 記憶體 alignof alignas

一 現象 先看一段程式碼: struct s1 { char s; int i; }; struct s2 { int i; double d; }; cout << "-------basic type" << endl; c

關於C語言記憶體,提高定址效率問題

前言: 計算機的記憶體都是以位元組為單位來劃分的,CPU一般都是通過地址匯流排來訪問記憶體的,一次能處理幾個位元組,就命令地址匯流排去訪問幾個位元組,32位的CPU一次能處理4個位元組,就命令地址匯流排一次讀取4個位元組,讀少了浪費主頻,讀多了也處理不了。64位的CPU一般

c語言記憶體與#pragma pack(n)

一、什麼是記憶體對齊,為什麼要記憶體對齊  現在計算機記憶體空間都是按照byte位元組劃分的,理論上講對任何型別的變數的訪問可以從任何地址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體地址上訪問,這就需要各種資料型別按照一定的規則在空間上排列,而不是一個接一個

Android平臺,C/C++程式碼記憶體問題(signal SIGBUS Error)

最近手機版本老出現崩潰,之前出現過,但很偶然。最近出現機率比較高,就跟查一下。 報了signal SIGBUS BUS Error,最終定位在uint32_t i32 = *((uint32_t*)m_data); 這句語出了問題, 確認m_data記憶體是正確的,並且在P

C++】記憶體和簡單的記憶體管理

記憶體管理 自己申請一個記憶體塊,用來存放構造的資料,使用placement new在記憶體上構造資料。 示例: //待操作的資料 struct Data { Data(int _a

c++ struct 記憶體

結構體的記憶體佈局依賴於cpu,作業系統,編譯器以及編譯時的選項。 考慮三點: 1.成員對齊 每個成員變數存放的位置相對於結構體起始位置的偏移量必須為該變數型別所佔用位元組數的倍數。 空缺的位元組由編譯器自動padding,padding的值根據記憶體分

c++記憶體中位元組問題

struct MyStruct  {  double dda1;  char dda;  int type  };  對結構MyStruct採用sizeof會出現什麼結果呢?sizeof(MyStruct)為多少呢?也許你會這樣求:  sizeof(MyStruct)=sizeof(double)+sizeo

c/c++ struct 記憶體

為了讓CPU能夠更舒服地訪問到變數,struct中的各成員變數的儲存地址有一套對齊的機制。這個機制概括起來有兩點:第一,每個成員變數的首地址,必須是它的型別的對齊值的整數倍,如果不滿足,它與前一個成員變數之間要填充(padding)一些無意義的位元組來滿足;第二,整個st

Linux下C記憶體

本文全文參考:http://blog.csdn.net/wendy260310/article/details/17675983 該部落格是在Linux下C++測試的,我在他的基礎上測試了C語言的結構體,環境採用Windows下DEV,由於都是GCC編譯器,所以其本質是一樣

C/c++中記憶體拷貝函式memcpy

原型:void*memcpy(void*dest, const void*src,unsigned int count);  功能:由src所指記憶體區域複製count個位元組到dest所指記憶體區域。 說明:src和dest所指記憶體區域不能重疊,函式返回指向des

C++虛擬函式表以及記憶體文章

C++虛擬函式表以及記憶體對齊文章 C++ 物件的記憶體佈局(上) https://blog.csdn.net/haoel/article/details/3081328 C++ 物件的記憶體佈局(下) https://blog.csdn.net/haoel/article/deta

C語言結構體(記憶體問題)

C語言結構體對齊也是老生常談的話題了。基本上是面試題的必考題。內容雖然很基礎,但一不小心就會弄錯。寫出一個struct,然後sizeof,你會不會經常對結果感到奇怪?sizeof的結果往往都比你宣告的變數總長度要大,這是怎麼回事呢?     開始學的時候,

C語言查缺補漏(七)結構體記憶體原則

忽略點七:結構體記憶體對齊原則 ​ 直到前幾個星期做了一道選擇題才知道,結構體元素的宣告順序可能影響結構體使用時所需的記憶體大小!!! ​ 一查才知道,在C語言中結構體有記憶體對齊原則,這個原則可以總結為兩點: ——資料成員對齊規則: ​ 結構體或聯合體的資料

C/C++ 記憶體原則及作用

struct/class/union記憶體對齊原則有四個: 1).資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第一個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小或者成員的子成員大小(只要該成員有子成員,比

c++記憶體的問題

#include <iostream> typedef class { public: struct { int b; int c; }a; struct { bool e; char f; }d;

C語言中的struct——記憶體

sizeof計算結構體大小的時候具體是怎樣計算的 記憶體對齊的原則是根據最寬資料型別的大小進行對齊的 struct A { char a; 1+1 short b; 2 int c; 4 }; 大小是8個位元組 要進行記憶體對齊,是

C++中什麼是記憶體

以下資料是我從別人的文章抽取出來的,我認為比較有利於理解。加上一點我的理解     接下來我們好好討論一下記憶體對齊的作用   1.平臺原因(移植原因):不是所有的硬體平臺都能訪問任意地址上的任意資料,某些硬體平臺只能在某些地址處取某些特定型別的資料,否則丟擲硬體異常