【轉】徹底搞清計算結構體大小和數據對齊原則

數據對齊:

許多計算機系統對基本數據類型合法地址做出了一些限制,要求某種類型對象的地址必須是
某個值K(通常是2,4或8)的倍數。這種對齊限制簡化了形成處理器和存儲器系統之間的接口的硬件
設計。例如,假設一個處理器總是從存儲器中取出8個字節,則地址必須為8的倍數。如果我們能保
證將所有的double類型數據的地址對齊成8的倍數,那么就可以用一個存儲器操作來讀或者寫值了。
否則,我們可能需要執行兩次存儲器訪問,因為對象可能被分放在兩個8字節存儲塊中。
當數據類型為結構體時,編譯器可能需要在結構體字段的分配中插入間隙,以保證每個結構元素都
? ? ? ? ?滿足它的對齊要求。而結構本身對它的地址也有一些對齊要求,此時可能需要在結構末尾填充一些
? ? ? ? ?空間,以滿足結構體整體的對齊----向結構體元素中最大的元素對齊。稍后會用代碼說明!!!
? ? ? ?
? ? ? ? ?Linux和Microsoft Windows的對齊方式有何不同:
? ? ? ? ? ? ? ?一.Linux的對齊策略:
在Linux中2字節數據類型(例如short)的地址必須是2的倍數,而較大的數據類型(例如int,int *
,float和double)的地址必須是4的倍數。也就是說Linux下要么2字節對齊,要么4字節對齊,沒
有其他格式的對齊。
? ? ? ? ? ? ? 二.Microsoft Windows的對齊策略:
在Windows中對齊要求更嚴--任何K字節基本對象的地址都必須是K的倍數,K=2,4,或者8.
特別地,double或者long long類型數據的地址應該是8的倍數。可以看出Windows的對齊策略和
Linux還是不同的。稍后用代碼說明!!!
?接下來用代碼和圖文說明兩者的對齊方式(不同的對齊方式產生的結構體大小不同):
測試代碼如下:
    /  //   filename:DataAlignment  /  #include<stdio.h>  typedef struct   {  char c;  int i[2];  double v;  }S;  int main()  {  printf("size of S = %d\n", sizeof(S));  return 0;  }  

?

程序中定義了一個結構體,在沒有任何數據對齊時內存布局如下:
一.在紅帽Linux i686上編譯編譯后結構S的布局如下:
? ? ? ? ? ? ? ??
由于要保證結構體每個元素都要數據對齊,因此必須在c和i[0]之間插入3字節的間隙(圖中陰影部分為編譯器插入的間隙)
使得i[0]和后面的元素的的偏移量都為4的倍數,這樣最終S結構大小為20字節。
運行程序結果為:
?size of S = 20
? ? ? ? ? ?
二.在Microsoft Windows 上編譯后S的內存布局如下:
在windows下int類型4個字節,因此int類型要向4字節對齊,double類型8字節,因此要向8字節對齊。因此在
c和i[0]之間插入3字節的間隙(圖中陰影部分),使得i[0]的偏移量為4的倍數,同時在i[1]和v之間插入4字節的間隙,
使得v的偏移量為8的倍數。這樣最終S結構的大小為24字節。
運行程序結果為:
?size of S = 24
? ? ? ? ? 從以上對比可以看出Linux下和windows下的對齊策略是不同的,這就導致在兩個平臺下結構體的大小不同。
? ? ? ? ? ?
? ? ? ? ?現在考慮如下代碼:
? ? ? ? ? ? ??
    #include<stdio.h>  typedef struct  {  int i;  int j;  char c;  }S1;  int main()  {  printf("size of S1 = %d\n", sizeof(S1));  return 0;  }  

?

可能很多人認為編譯后運行結果為9,以為結構體的每個元素都滿足各自的對齊要求。其實不然,別忘了還有要考慮
結構體整體的對齊。假如有如下聲明:
S1 ?d[4];
如果這樣分配9個字節,不可能滿足d的每個元素的對齊要求,因為這些元素的地址分別為xd,xd+9,xd+18,
xd+27。這樣只有第一個元素滿足4字節對齊的要求,而其他的元素的地址都不是4的倍數。

因此編譯器會在結構體的末尾填充3字節滿足結構體整體的對齊要求,填充后的內存布局如下:
這樣一來,d的元素的地址分別為xd,xd+12,xd+24,xd+36,滿足4字節的整數倍,這樣最終S1的大小
為12字節,而不是9字節.

總結:通過代碼的對比,可以看出Linx和Windwos的數據對齊有所差異,這就導致
在一些情況下兩者平臺結構體類型大小的不同。通過以上示例分析我們可以很簡單的
計算出在任何平臺下結構體的大小。讀者可以找相關的練習題繼續練習下,驗證結果
的正確性。相信仔細閱讀本文應該能搞定所有類似的問題!!!
原文地址:http://blog.csdn.net/qianghaohao/article/details/51011418

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260507.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260507.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260507.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python里pip是什么意思_python使用pip的方法是什么

python使用pip的方法是什么 發布時間&#xff1a;2020-08-25 11:51:08 來源&#xff1a;億速云 閱讀&#xff1a;104 作者&#xff1a;小新 小編給大家分享一下python使用pip的方法是什么&#xff0c;相信大部分人都還不怎么了解&#xff0c;因此分享這篇文章給大家參考一下&am…

Pytorch 學習率衰減 之 余弦退火與余弦warmup 自定義學習率衰減scheduler

學習率衰減&#xff0c;通常我們英文也叫做scheduler。本文學習率衰減自定義&#xff0c;通過2種方法實現自定義&#xff0c;一是利用lambda&#xff0c;另外一個是繼承pytorch的lr_scheduler import math import matplotlib.pyplot as plt import numpy as np import torch i…

c++ 字符串賦給另一個_7.2 C++字符串處理函數

點擊上方“C語言入門到精通”&#xff0c;選擇置頂第一時間關注程序猿身邊的故事作者閆小林白天搬磚&#xff0c;晚上做夢。我有故事&#xff0c;你有酒么&#xff1f;C字符串處理函數C語言和C提供了一些字符串函數&#xff0c;使得用戶能很方便地對字符串進行處理。這些是放在…

如何檢測遠程主機上的某個端口是否開啟

有時候我們要測試遠程主機上的某個端口是否開啟&#xff0c;無需使用太復雜的工作&#xff0c;windows下就自帶了工具&#xff0c;那就是telnet。怎么檢測呢&#xff0c;按下面的步驟&#xff1a; 1、安裝telnet。我的win7下就沒有telnet&#xff0c;在cmd下輸入telnet提示沒有…

Windows10 + WSL (Ubuntu) + Anaconda + vscode 手把手配置python運行環境(含虛擬環境)

配置WSL windows桌面下&#xff0c;按下面順序可以找到 "啟動或關閉windows功能” &#xff0c; 開始 -> 設置 -> 應用 -> 應用和功能 -> 可選功能 -> 相關設置下 更多Windows功能&#xff08;滾動鼠標到底部&#xff09;點擊后&#xff0c;會彈出 啟動或…

Inline函數使用注意事項

Inline函數使用注意事項 1.在一個文件中定義的inline函數不能再另一個文件中使用 2.inline函數應簡潔&#xff0c;只有少數幾個語句。 3.在inline函數中不能有循環&#xff0c;if&#xff0c;switch語句。 4.inline函數要在調用和聲明前定義&#xff01;&#xff01;&#xff0…

2019編譯ffepeg vs_如何在windows10下使用vs2017編譯最新版本的FFmpeg和ffplay

該文章描述了如何在windows10 64位系統下面編譯出FFmpeg的庫及其自帶的ffplay播放器&#xff0c;而且全部采用最新的版本&#xff0c;這樣我們可以在vs2017的ide下調試ffplay&#xff0c;能使我們更容易學習FFmpeg的架構以及音視頻播放器的原理。步驟&#xff1a;1.安裝vs2017在…

訓練集山準確率高測試集上準確率很低_推薦算法改版前的AB測試

編輯導語&#xff1a;所謂推薦算法就是利用用戶的一些行為&#xff0c;通過一些數學算法&#xff0c;推測出用戶可能喜歡的東西&#xff1b;如今很多軟件都有這樣的操作&#xff0c;對于此系統的設計也會進行測試&#xff1b;本文作者分享了關于推薦算法改版前的AB測試&#xf…

C#實現漸變顏色的Windows窗體控件

C#實現漸變顏色的Windows窗體控件! 1,定義一個BaseFormGradient,繼承于System.Windows.Forms.Form2,定義三個變量: privateColor _Color1 Color.Gainsboro; privateColor _Color2 Color.White; privatefloat_ColorAngle 0f;3,重載OnPaintBackground方法 protecte…

ios7開發學習筆記-包括c oc 和ios介紹

請查看我的新浪資料分享 http://iask.sina.com.cn/u/2430843520 轉載于:https://www.cnblogs.com/langtianya/p/3708298.html

Windows下 jupyter notebook 運行multiprocessing 報錯的問題與解決方法

文章目錄測試用的代碼錯誤解決方法測試用的代碼 下面每一個對應一個jupyter notebook的單元格 import time from multiprocessing import Process, Queuedef generator():c 0while True:time.sleep(1.0) # read somethingyield cc 1%%timeds generator() for i in range(3…

如何將javaweb項目部署到linux下

以下是對將javaweb項目部署到linux下的方法進行了詳細的分析介紹一般都在windows下開發的現在部署到linux下將項目達成war包(用eclipse項目右鍵>Export>選擇war file)將tomcat(用winSCP當然你也可以用secureCRT用securCRT需要建立sftp(即上傳文件的目錄)用put tomcat命令…

vc mysql_vc6.0連接mysql數據庫

一、MySQL的安裝Mysql的安裝去官網下載就可以。。。最新的是5.7版本。。二、VC6.0的設置(1)打開VC6.中選0 工具欄Tools菜單下的Options選項&#xff0c;在Directories的標簽頁中右邊的“Show directories for:”下拉列表中“Includefiles”&#xff0c;然后在中間列表框中添加你…

python class用法_python原類、類的創建過程與方法

【小宅按】今天為大家介紹一下python中與class 相關的知識……獲取對象的類名python是一門面向對象的語言&#xff0c;對于一切接對象的python來說&#xff0c;咱們有必要深入的學習與了解一些知識首先大家都知道&#xff0c;要獲取一個對象所對應的類&#xff0c;需要使用clas…

網易公開課

計算機科學及編程導論 http://v.163.com/special/opencourse/bianchengdaolun.html 抽象編程 http://v.163.com/special/opencourse/abstractions.html轉載于:https://www.cnblogs.com/anyboo/archive/2012/08/24/2653537.html

深度學習中的一些常見的激活函數集合(含公式與導數的推導)sigmoid, relu, leaky relu, elu, numpy實現

文章目錄Sigmoid(x)雙曲正切線性整流函數 rectified linear unit &#xff08;ReLu&#xff09;PReLU(Parametric Rectified Linear Unit) Leaky ReLu指數線性單元 Exponential Linear Units &#xff08;ELU&#xff09;感知機激活%matplotlib inline %config InlineBackend.f…

最牛X的GCC 內聯匯編

正如大家知道的&#xff0c;在C語言中插入匯編語言&#xff0c;其是Linux中使用的基本匯編程序語法。本文將講解 GCC 提供的內聯匯編特性的用途和用法。對于閱讀這篇文章&#xff0c;這里只有兩個前提要求&#xff0c;很明顯&#xff0c;就是 x86 匯編語言和 C 語言的基本認識。…

mysql的告警日志_MySQL Aborted connection告警日志的分析

前言&#xff1a;有時候&#xff0c;連接MySQL的會話經常會異常退出&#xff0c;錯誤日志里會看到"Got an error reading communication packets"類型的告警。本篇文章我們一起來討論下該錯誤可能的原因以及如何來規避。1.狀態變量Aborted_clients和Aborted_connects…

hosts多個ip對應一個主機名_一個簡單的Web應用程序,用作連接到ssh服務器的ssh客戶端...

WebSSH一個簡單的Web應用程序&#xff0c;用作連接到ssh服務器的ssh客戶端。它是用Python編寫的&#xff0c;基于tornado&#xff0c;paramiko和xterm.js。特征支持SSH密碼驗證&#xff0c;包括空密碼。支持SSH公鑰認證&#xff0c;包括DSA RSA ECDSA Ed25519密鑰。支持加密密鑰…

Yii框架中使用PHPExcel導出Excel文件

Yii框架中使用PHPExcel導出Excel文件http://www.cnblogs.com/wgx214/p/3709521.html轉載于:https://www.cnblogs.com/flying-tx/p/3714530.html