1. 程式人生 > >C-結構體對齊

C-結構體對齊

技術群的筒子們有時候會提到結構體對齊,說實話這個問題還不是幾句話能講清楚的。這個問題網上一搜一大把,已經有無數的前輩總結過。看了很多網上的資料,根據我個人的一些理解,再總結一下,配了些圖片,希望大家能看懂。

首先是結構體對齊規則:

1、對於n個位元組的元素,它的首地址要能被n整除

         eg:int—4個位元組的元素,它為結構體的第一個元素時,起始地址應能被4整除

                  double—8個位元組的元素,它為結構體的第一個元素時,起始地址應能被8整除

2、結構體成員在記憶體中順序存放,所佔記憶體地址依次增高,第一個成員處在低地址處,最後一個成員處在高地址處,但結構體成員之間的記憶體分配不一定是連續的

3、對待每個成員,類似於對待單個n位元組元素一樣,依次為每個元素找一個合適的首地址,使其符合第一條對齊原則

4、編譯器可設定對齊引數X,但這個X並不是結構體成員的實際對齊引數,結構體中每個成員的對齊引數N這樣計算

         N= min(sizeof(成員型別),X)

5、整個結構體的長度必須是各成員所使用的對齊引數N中最大的那個值的整數倍

         即總長度LEN= {max(N1,N2,……,N)}的最小整數倍

6、當結構體成為為陣列時,將陣列的每個元素當一個成員來看待

7、當結構體成為類結構型別時,那麼該過程是個遞迴過程,且把該成員當成一個整體來看待

上面的規則有點暈,對照著看下面的例子微笑

#pragma pack(8)   //設定編譯器以8位元組對齊
struct A
{
char c;//①成員的對齊引數N1=  min(sizeof(char) , 8)     = 1
double d;//②成員的對齊引數N2 = min(sizeof(double) , 8) = 8
short s;//③成員的對齊引數N3 = min(sizeof(short) , 8)    = 2
int i;//④成員的對齊引數N4 = min(sizeof(int) , 8)      = 4
}
結構體的總成都LEN = {max(N1,N2,N3,N4)}的整數倍 ,所以長度LEN必須是8的整數倍,從下面的記憶體分佈圖中可看出,總長度是24位元組


#pragma pack(4)  //設定編譯器以4位元組對齊
struct A
{
char c;//①成員的對齊引數N1=  min(sizeof(char) , 4)     = 1
double d;//②成員的對齊引數N2 = min(sizeof(double) , 4) = 4
short s;//③成員的對齊引數N3 = min(sizeof(short) , 4)    = 2
int i;/④成員的對齊引數N4 = min(sizeof(int) , 4)       = 4
}
結構體的總成都LEN = {max(N1,N2,N3,N4)}的整數倍 ,所以長度LEN必須是4的整數倍,從下面的記憶體分佈圖中可看出,總長度是20位元組


#pragma pack(2)  //設定編譯器以2位元組對齊
struct A
{
char c;//①成員的對齊引數N1=  min(sizeof(char) , 2)     = 1
double d;//②成員的對齊引數N2 = min(sizeof(double) , 2) = 2
short s;//③成員的對齊引數N3 = min(sizeof(short) , 2)    = 2
int i;//④成員的對齊引數N4 = min(sizeof(int) , 2)       = 2
}
結構體的總成都LEN = {max(N1,N2,N3,N4)}的整數倍 ,所以長度LEN必須是2的整數倍,從下面的記憶體分佈圖中可看出,總長度是16位元組


#pragma pack(1)  //設定編譯器以1位元組對齊
struct A
{
char c;//①成員的對齊引數N1=  min(sizeof(char) , 1)     = 1
double d;//②成員的對齊引數N2 = min(sizeof(double) , 1) = 1
short s;//③成員的對齊引數N3 = min(sizeof(short) , 1)    = 1
int i;//④成員的對齊引數N4 = min(sizeof(int) , 1)        = 1
}

這個就不多說了,結構體總長15位元組

以上的例子都是在32位的系統上試的,這裡兩個結構體成員之間的“空隙”我用“cc”來填充,這純粹是畫起來方便,VS2010中這些“空隙”裡的值都是0。

當然我之前在單步執行別的C程式的時候發現,很多初始化的記憶體、棧空間,都以"cc"字元來填充。最近在一本書上看到了解釋,抄錄在此:

對於X86處理器來說,0xcc是不錯的填充數值,因為它是斷點中斷(int 03h)的機器碼,如果你在偵錯程式中執行程式並試圖執行一段資料而不是執行程式碼時,就會陷入斷點。

另外,使用0xcc的另一個好處是它可以很容易從記憶體轉儲的資訊中識別出來

相關推薦

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

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

C-結構

技術群的筒子們有時候會提到結構體對齊,說實話這個問題還不是幾句話能講清楚的。這個問題網上一搜一大把,已經有無數的前輩總結過。看了很多網上的資料,根據我個人的一些理解,再總結一下,配了些圖片,希望大家能看懂。 首先是結構體對齊規則: 1、對於n個位元組的元素,它的首地址要能

c結構深刻理解

1. 先看下面的例子: struct A{    char c1;    int i;    short s;    int j; }a; struct B{    int i;    int j;      short s;    char c1; }b; 結構A沒有遵守位元組對齊原則(為了區分,我將它叫做

c++結構

參考各資料得出自己使用的公式:1、(當前偏移量+當前填充數)%當前變數大小=02、(總偏移大小+末尾填充數)%最寬變數大小=0必須先滿足1、再滿足2。例如程式碼如下:struct A{int a;//(當前偏移量0+當前填充數0)%當前變數大小4=0char b;// (當前

C/C++結構_思索

       最近在看對齊方面的問題,發現大家在面試筆試的時候,對方基本上都是會拿包含陣列的結構體、或者包含結構體的結構體來考大家,而不會單純的拿幾個int,long,或者double組合在一起考,因為那樣太簡單,找了些資料,幫助自己也幫助大家理解下,共同交流!      

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

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

C++關於結構

說明: 結構體的sizeof值,並不是簡單的將其中各元素所佔位元組相加,而是要考慮到儲存空間的位元組對齊問題。這些問題在平時程式設計的時候也確實不怎麼用到,但在一些筆試面試題目中出是常常出現,一、解釋 現代計算機中記憶體空間都是按照byte劃分的,從理論上講

C語言結構與不對設定總結

相信不同的編譯平臺間的預設設定差異給大家帶來了很多困擾。在此,僅就結構體對齊解析下之間的差異設定方法。 1.gcc中結構體預設是4個位元組對齊,即為32的倍數。 1.1修改位元組對齊: struct data{ int a; char b; char c; }__

13)結構問題

ngs dmi nts min mage ++ image http c語言 詳細可以看 臺式機的 C:\Documents and Settings\Administrator\桌面\C++基礎教程完整版視頻\01_C語言提高\d

結構

str center 但是 內存 read 地址 形式參數 class area 1 C語言裏可以在一個存儲區裏記錄多個相關數字這種存儲區的類型叫結構體類型,這種類型需要首先創建出來然後才能使用 2 結構體類型存儲區裏包含多個子存儲區,每個子存儲區可以記錄一個數字,結構體中

linux中結構【轉】

src double 無需 fine types 查看 真理 blog 多個 轉自:https://blog.csdn.net/suifengpiao_2011/article/details/47260085 linux中定義對齊字節 typedef struct

逆向基礎之結構

eof 成員對齊 偏移 str 最大 結構體 基礎 數據 sizeof 遵循以下原則,數據成員對齊;結構體大小;結構體有某些成員大,最大對齊,對齊參數筆結構體的sizeof小,偏移以此為準。struct{ char a;int b;char c;}a 1b,補3b 4bc

結構總結

結構體對齊 結構體對齊到底是什麼,看了網上很多的解答,彙總成個人經驗 什麼是結構體對齊 結構體對齊規則 考慮一個問題,為什麼要設計記憶體對齊的處理方式呢? ENDING 結構體對齊到底是什麼,看了網上很多

結構——結構記憶體佈局

在C語言中,可以通過#pragma pack(n)來指定結構體按n位元組對齊(這裡的n是2的較小整數次冪)。如果程式設計者不指定對齊位元組數,那麼預設的會按照結構體中最長那一項對齊,如在64位作業系統中,當結構體中出現(void *),(long)型別,則必然是按照8位元組對齊;當最大的是int,那麼就按照4

結構——結構體內存布局

聲明 amp pri 最大的 結構 sdn int spa turn 在C語言中,可以通過#pragma pack(n)來指定結構體按n字節對齊(這裏的n是2的較小整數次冪)。如果程序設計者不指定對齊字節數,那麽默認的會按照結構體中最長那一項對齊,如在64位操作系統中,當結

sizeof與strlen用法詳解(結構)

#include<stdio.h> int main(int argc,char **argv) { unsigned char a[10] ={1,2,1,2,3,4}; unsigned char a1[10] ={0,0,0,0,0,0}; char *

結構問題.

Intel、微軟等公司曾經出過一道類似的面試題: 2.1 自然對界   struct是一種複合資料型別,其構成元素既可以是基本資料型別(如int、long、float等)的變數,也可以是一些複合資料型別(如array、struct、union等)的資料單元。對於結構體,編譯器會自動進行成員變數的對齊,以提高

結構的原則及原因分析

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

64位系統結構訪問段錯誤

先放程式碼: #include struct s { char c; int b; }; int main(void){ printf("sizeof (struct s) = %d.\n

結構問題以及強制型別轉換問題總結

一、什麼是對齊     現在使用的計算機中記憶體空間都是按照位元組劃分的,從理論上講似乎對任何型別的變數的訪問都可以從任何地址開始,但實際上計算機系統對於基本資料型別在記憶體中的存放位置都有限制。舉個例子,一個變數佔用n個位元組,則該變數的起始地址必須能夠被n整除,即存放