數據結構對齊

數據結構對齊是代碼編譯後在記憶體的布局與使用方式。包括三方面內容:數據對齊數據結構填充(padding)與包入(packing)。

基本介紹

  • 中文名:數據結構對齊
  • 內容:數據對齊等
  • 領域:計算機
簡介,定義,x86體系結構,C語言struct在x86上的對齊,預設packing與#pragma pack,數組步長,類型雙關,

簡介

現代計算機一般是32比特或64比特地址對齊,如果要訪問的變數沒有對齊,可能會觸發匯流排錯誤。
當數據小於計算機的字(word)尺寸,可能把幾個數據元素放在一個字中,稱為包入(packing)。
許多程式語言自動處理數據結構對齊。Ada語言PL/IPascal,某些C語言C++實現,D語言,Rust,與彙編語言允許特別控制對齊的方式。

定義

記憶體地址a被稱為n位元組對齊,當an的倍數(n應是2的冪)。
一次記憶體訪問被稱為對齊的,當被訪問的數據長度為n位元組且該數據地址為n位元組對齊。如果記憶體未對齊,稱作misaligned。顯然,位元組訪問總是對齊的。
記憶體指針是對齊的,如果它所指的數據是對齊的。指向聚合數據(aggregate data,如struct或數組)是對齊的,若且唯若它的每個組成數據是對齊的。

x86體系結構

x86體系架構最初是不要求記憶體對齊。一些SSE2指令要求數據是128比特(16位元組)對齊。有些CPU指令用於未對齊訪問如MOVDQU。讀寫記憶體操作僅在對齊時才是原子的。

C語言struct在x86上的對齊

C語言數據結構內的成員先後順序不能改變。
常見的C語言編譯器在32比特x86上,double是8位元組對齊,但Linux上是4位元組對齊(編譯選項-malign-double實現8位元組對齊)。
一些編譯器(Microsoft,Borland,GNU,等等)使用#pragmadirective指定對齊的包入(packing)。例如:
#pragma pack(push)  /* push current alignment to stack */#pragma pack(1)     /* set alignment to 1 byte boundary */struct MyPackedData{        char Data1;        long Data2;        char Data3;};#pragma pack(pop)   /* restore original alignment from stack */
這個結構在32位系統的大小為6位元組。

預設packing與#pragma pack

Microsoft編譯器的項目預設packing(編譯選項/Zp)與#pragma pack指令。#pragma pack指令僅能減少packing尺寸。

數組步長

數組步長(stride of an array,也稱increment, pitch或step size)是程式設計時,相鄰數組元素在記憶體中的開始地址的距離,度量單位可以是位元組或者數組元素個數。步長不可小於數組元素的尺寸,但可以大於,表示有填充的位元組。
數組步長如果等於數組元素的尺寸,則數組在記憶體中是連續的。這可稱為單位步長(unit stride)。非單位步長適用於二維數組多維數組

類型雙關

類型雙關計算機科學的術語,指任何編程技術能顛覆或者繞過一門程式設計語言類型系統,以達成在形式語言內部難以甚至不可能實現的效果。
C語言C++語言,語法結構如類型轉換union,以及C++增加的reinterpret_cast運算符,用於實現類型雙關。
Pascal語言使用records與variants來按照多種方法處理特定數據類型。

相關詞條

熱門詞條

聯絡我們