結構體為什麼要4位元組對齊?
sizeof與struct——求結構體大小的計算方法
sizeof淺析(一)——求結構體大小 這篇文章講了sizeof求結構體大小的計算方法,並給出可以套用的準則:
一、儲存變數時地址要求對齊,編譯器在編譯程式時會遵循兩條原則:
(1)結構體變數中成員的偏移量必須是成員大小的整數倍(0被認為是任何數的整數倍)
(2)結構體大小必須是所有成員大小的整數倍,也即所有成員大小的公倍數。
二、 對於巢狀的結構體,需要將其展開。對結構體求sizeof時,上述兩種原則變為:
(1)展開後的結構體的第一個成員的偏移量應當是被展開的結構體中最大的成員的整數倍。
(2)結構體大小必須是所有成員大小的整數倍,這裡所有成員計算的是展開後的成員,而不是將巢狀的結構體當做一個整體。
為什麼?
但是編譯器為什麼要這麼做,以下是我的理解。
為什麼要對齊?
因為在32位作業系統(雖然64位作業系統,但是為了保證相容性,程式設計仍然主要考量32位)中,資料匯流排是32位,地址匯流排是32位。
地址匯流排是32位,意味著定址空間是按4遞增的;資料匯流排32位意味著一次可讀寫4byte。
考慮這樣一個結構體
struct stu1
{
char c1;
int i;
char c2;
}
不對齊就意味著,當我們執行stu1.i 時,需要讀取記憶體兩次。而對齊後,就只需要讀取一次,眾所周知,I/O操作是很耗時的,編譯器做出對齊的選擇也就好理解。
為什麼不完全按照4位元組對齊的?
既然對齊可以避免上述的問題,為什麼不將所有儲存小於4byte的資料型別(char, short等)統統按4byte對齊呢?
考慮這樣一個結構體
struct stu2
{
char c;
short s;
int i;
double d;
}
為什麼編譯器採用B方案,而不採用A方案?
還是因為32資料線一次讀取4個位元組,
採用方案A,讀取stu2.c,或者stu2.s,要一次讀取4個byte,再捨棄無關記憶體的資料。
採用方案B,讀取stu2.c,或者stu2.s,也是要一次讀取4個byte,再捨棄無關記憶體中的資料。
同樣的I/O操作,相比之下,明顯方案B更節省記憶體。
補充: 如上圖中,所示8位元組的資料型別,比如double, long long,必須要讀取兩次記憶體。
明白這兩點,再回看上面結構體大小的計算方法,就簡單多了,也不用死記爛背了。
另外,寫程式碼時也知道怎樣節省記憶體了(雖然大多數時間不用考慮這點)。
相關推薦
結構體為什麼要4位元組對齊?
sizeof與struct——求結構體大小的計算方法 sizeof淺析(一)——求結構體大小 這篇文章講了sizeof求結構體大小的計算方法,並給出可以套用的準則: 一、儲存變數時地址要求對齊,編譯器在編譯程式時會遵循兩條原則: (1)結構體變數
更改結構體的記憶體位元組對齊方式--經典
為什麼要對齊? 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何地址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體地址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。 對齊的作用和原因:
結構體4位元組對齊規則的詳解
一 四位元組對齊的規則 C++中結構體變數的儲存為什麼有個4位元組對齊的規則,這裡是假設32位機器上,CPU在讀取記憶體資料的時候4位元組對齊會取得更快的速度;這是因為:1位元組8位,4位元組正好32位,而32位機器的暫存器,地址什麼的都是32位的,正好一次處理就完成。
3.c語音結構體成員內存對齊詳解
定義 pre 形狀 sed 兩個 分配 我們 替代 images 一.關鍵一點 最關鍵的一點:結構體在內存中是一個矩形,而不是一個不規則形狀 二.編程實戰 1 #include <stdlib.h> 2 #inc
上、下位機軟件通信時,結構體的內存對齊問題
代碼 ini tle www. init 軟件 。。 === 默認 嵌入式開發,上位機軟件與下位機軟件通信發送結構體數據時,由於兩者 IDE 通常不同 (因此編譯器通常也不同),導致上下位軟件各自編譯器的默認 “對齊系數” 也可能不同。 此時需在代碼中指定一個一致的 “對齊
結構體的大小 記憶體對齊
結構體的大小 記憶體對齊 Struct A { int a; int b; }; int main() { Printf(“%d\n”,sizeof(struct A)); 共佔8位
結構體的大小,對齊規則
每個成員的偏移量必須是該成員大小的倍數 結構體的大小是最大成員的倍數 基本型別資料對齊就是資料在記憶體中的偏移地址必須等於一個字的倍數, 按這種儲存資料的方式,可以提升系統在讀取資料時的效能。為了對齊資料, 可能必須
c語言結構體巢狀的對齊方式
1:在程式碼中有結構體巢狀的方式,又需要獲取每個變數的地址。那麼需要了解結構體巢狀和單一結構體的一些對齊方面的規則。2:對於嵌入式的裝置來說,對齊很重要,有些cpu不支援不對齊的訪問方式,有的cpu支援,只是效率上會降低。3:arm中預設編譯的時候會進行對齊。規則一:結構體中
點陣圖4位元組對齊問題
在自己對影象資料進行處理的時候,會有位元組對其的問題,由於之前使用的影象大都是8bit或者是24bit,32bit的影象,使用的對其公式是(pixelwidth*channel+3)/4*4。後面也有看到有些寫法如:(width * bitCounts + 31) / 32
讓地址4位元組對齊的辦法
假設p是一個指標址或者是一個變數,通過以下程式碼實現p是4的整數倍,如果是地址,則實現4位元組對齊 程式碼1: while (p & 0x03){ p++;} 如果p是4整數倍,條件為0,退出,如果p多1,p最後2位會從01,10,11直到00。 程式碼2:
什麼是C語言結構體位元組對齊,為什麼要對齊?
一、概念 對齊跟資料在記憶體中的位置有關。如果一個變數的記憶體地址正好位於它長度的整數倍,他就被稱做自然對齊。比如在32位cpu下,假設一個整型變數的地址為0x00000004,那它就是自然對齊的。 二、為什麼要位元組對齊 需要位元
C語言 結構體位元組對齊問題
摘選自這位大神的部落格 方法一: 結構體在記憶體中分配一塊連續的記憶體,但結構體內的變數並不一定是連續存放的,這涉及到記憶體對齊。原則1 資料成員對齊規則:結構(struct或聯合union)的資料成員,第一個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小的整
詳解結構體、類等記憶體位元組對齊
先說個題外話:早些年我學C程式設計時,寫過一段解釋硬碟MBR分割槽表的程式碼,對著磁碟編輯器怎麼看,怎麼對,可一執行,結果就錯了。當時除錯也不太會,又根本沒聽過結構體對齊這一說,所以,問題解決不了,好幾天都十分糾結。後來萬般無奈請教一個朋友,才獲悉可能是結構體對齊的事,一查、一改,果真如此。 &
結構體的位元組對齊
在用sizeof運算子求算某結構體所佔空間時,並不是簡單地將結構體中所有元素各自佔的空間相加,這裡涉及到記憶體位元組對齊的問題。 1) 結構體變數的首地址能夠被其最寬基本型別成員的大小所整除; 2) 結構體每個成員相對結構體首地址的偏移量都是成員大小的整數倍; 3) 結構體的總大小為結構
C 構造型別 陣列、列舉、聯合體、結構體(位段) 位元組對齊 和 大小端儲存
列舉 .列舉:被命名的標籤常量(對事物的列出) ---型別的構造------- enum key{ UP, //成員<標籤常量:預設第一個為0 後一個總是前一個的值加一> DOWN, L
C/C++ 結構體位元組對齊詳解
結構體的sizeof 先看一個結構體: struct S1 { char c; int i; }; 12345 structS1{charc;in
結構體與類的位元組對齊(終極方案,簡單易懂)
先記住常用型別在32和64位的位元組 型別 32位 64位 char 1 1 int 4 4 short 2 2 float 4 4 double 8 8
C/C++結構體位元組對齊詳解
前提:為了訪問速度和效率,需要各種型別資料按照一定的規則在空間上排列; 不是所有的硬體平臺都能訪問任意地址上的任意資料的;某些硬體平臺只能在某些地址處取 某些特定型別的資料,否則丟擲硬體異常。 為了訪問未對⻬的記憶體,處理器需要作兩次記憶體訪問;⽽對⻬的記憶體訪問僅需要
C語言結構體的位元組對齊例項【C語言筆試題】
一、筆試題目:在一個64位的作業系統中定義如下結構體: <span style="font-family:Microsoft YaHei;font-size:12px;">struct st_task { uint16_t id; uint32
結構體和聯合體的位元組對齊問題
為了提速之類的,在結構體和聯合體的記憶體塊中,是按照一定的規則安排的 聯合體: 聯合體的記憶體不會為了所有成員安排,而是隻取最大的成員的所需記憶體大小,每次只能使用其中一個成員。但是有一個問題: typedef union { char a; int[5] b;