国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++面試題之結構體內存對齊計算問題總結大全

2020-01-26 13:58:54
字體:
來源:轉載
供稿:網友

前言

本文給大家介紹的是關于C++結構體內存對齊計算的相關內容,內存對齊計算可謂是筆試題的必考題,但是如何按照計算原則算出正確答案一開始也不是很容易的事,所以專門通過例子來復習下關于結構體內存對齊的計算問題。話不多說,來一起看看詳細介紹吧。

編譯環境:vs2015

對齊原則:

      原則1:數據成員對齊規則:結構(struct)(或聯合(union))的數據成員,第一個數據成員放在offset為0的地方,以后每個數據成員的對齊按照#pragma pack指定的數值和這個數據成員自身長度中,比較小的那個進行。

      原則2:結構(或聯合)的整體對齊規則:在數據成員完成各自對齊之后,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大數據成員長度中,比較小的那個進行。

      原則3:結構體作為成員:如果一個結構里有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍地址開始存儲。

默認對齊值:

Linux 默認#pragma pack(4)

window 默認#pragma pack(8)

注:可以通過預編譯命令#pragma pack(n) ,n=1,2,4,8,16來改變這一系數,其中的n就是指定的“對齊系數”。

例一:一字節對齊

第一步: 成員數據對齊

#pragma pack(1)struct AA { int a; //長度4 < 1 按1對齊;偏移量為0;存放位置區間[0,3] char b; //長度1 = 1 按1對齊;偏移量為4;存放位置區間[4] short c; //長度2 > 1 按1對齊;偏移量為5;存放位置區間[5,6] char d; //長度1 = 1 按1對齊;偏移量為6;存放位置區間[7] //整體存放在[0~7]位置區間中,共八個字節。};#pragma pack()

第二步: 整體對齊

整體對齊系數 = min((max(int,short,char), 1) = 1,所以不需要再進行整體對齊。整體大小就為8。

圖示如下:

例二:二字節對齊

第一步: 成員數據對齊

#pragma pack(2)struct AA { int a; //長度4 > 2 按2對齊;偏移量為0;存放位置區間[0,3] char b; //長度1 < 2 按1對齊;偏移量為4;存放位置區間[4] short c; //長度2 = 2 按2對齊;偏移量要提升到2的倍數6;存放位置區間[6,7] char d; //長度1 < 2 按1對齊;偏移量為7;存放位置區間[8];共九個字節};#pragma pack()

第二步: 整體對齊

整體對齊系數 = min((max(int,short,char), 2) = 2,將9提升到2的倍數,則為10.所以最終結果為10個字節。

圖示如下:(X為補齊部分)

例三:四字節對齊

第一步: 成員數據對齊

#pragma pack(4)struct AA { int a; //長度4 = 4 按4對齊;偏移量為0;存放位置區間[0,3] char b; //長度1 < 4 按1對齊;偏移量為4;存放位置區間[4] short c; //長度2 < 4 按2對齊;偏移量要提升到2的倍數6;存放位置區間[6,7] char d; //長度1 < 4 按1對齊;偏移量為7;存放位置區間[8];總大小為9};#pragma pack()

第二步: 整體對齊

整體對齊系數 = min((max(int,short,char), 4) = 4,將9提升到4的倍數,則為12.所以最終結果為12個字節。

圖示如下:(X為補齊部分)

例三:八字節對齊

第一步: 成員數據對齊

#pragma pack(8)struct AA { int a; //長度4 < 8 按4對齊;偏移量為0;存放位置區間[0,3] char b; //長度1 < 8 按1對齊;偏移量為4;存放位置區間[4] short c; //長度2 < 8 按2對齊;偏移量要提升到2的倍數6;存放位置區間[6,7] char d; //長度1 < 8 按1對齊;偏移量為7;存放位置區間[8],總大小為9};#pragma pack()

第二步: 整體對齊

整體對齊系數 = min((max(int,short,char), 8) = 4,將9提升到4的倍數,則為12.所以最終結果為12個字節。圖示如上。

注:可以通過stddef.h庫中的offsetof宏來查看對應結構體元素的偏移量。

例四:結構體中包含結構體的運算

整體計算過程如下

struct EE{ int a; //長度4 < 8 按4對齊;偏移量為0;存放位置區間[0,3] char b; //長度1 < 8 按1對齊;偏移量為4;存放位置區間[4] short c; //長度2 < 8 按2對齊;偏移量由5提升到6;存放位置區間[6,7] //結構體內部最大元素為int,由于偏移量為8剛好是4的整數倍,所以從8開始存放接下來的struct FF struct FF { int a1; //長度4 < 8 按4對齊;偏移量為8;存放位置區間[8,11] char b1; //長度1 < 8 按1對齊;偏移量為12;存放位置區間[12] short c1; //長度2 < 8 按2對齊;偏移量為13,提升到2的倍數14;存放位置區間[14,15] char d1; //長度1 < 8 按1對齊;偏移量為16;存放位置區間[16] }; //整體對齊系數 = min((max(int,short,char), 8) = 4,將內存大小由17補齊到4的整數倍20 char d;  //長度1 < 8 按1對齊;偏移量為21;存放位置區間[21] //整體對齊系數 = min((max(int,short,char), 8) = 4,將內存大小由21補齊到4的整數倍24};

圖示如下:

例五:再來一個嵌套結構體的計算

整體計算過程如下

struct B { char e[2]; //長度1 < 8 按2對齊;偏移量為0;存放位置區間[0,1] short h; //長度2 < 8 按2對齊;偏移量為2;存放位置區間[2,3] //結構體內部最大元素為double,偏移量為4,提升到8,所以從8開始存放接下來的struct A struct A { int a; //長度4 < 8 按4對齊;偏移量為8;存放位置區間[8,11] double b; //長度8 = 8 按8對齊;偏移量為12,提升到16;存放位置區間16,23] float c; //長度4 < 8,按4對齊;偏移量為24,存放位置區間[24,27] }; //整體對齊系數 = min((max(int,double,float), 8) = 8,將內存大小由28補齊到8的整數倍32};

圖示如下:

小結:當#pragma pack的n值等于或超過所有數據成員長度的時候,這個n值的大小將不產生任何效果。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 侯马市| 丹巴县| 鄂州市| 临城县| 兰州市| 乐亭县| 凤阳县| 邛崃市| 唐海县| 汉阴县| 香格里拉县| 涞源县| 江山市| 内乡县| 贵溪市| 嵊州市| 错那县| 金门县| 清涧县| 邳州市| 偏关县| 蚌埠市| 黄龙县| 天镇县| 兴城市| 永丰县| 利辛县| 浑源县| 云龙县| 绥江县| 张家港市| 大同县| 驻马店市| 手机| 普安县| 和龙市| 平昌县| 镇巴县| 远安县| 扎鲁特旗| 抚州市|