從相似微軟面試題講起講字節對齊

#include <stdio.h>

#pragma pack(8)

struct example1
{
	short a;
	long b;
};
struct example2
{
	char c;
	example1 struct1;
	short e;
};

int main(void)
{
	example2 struct2;
	
	printf("%u\n", sizeof(example1));
	printf("%u\n", sizeof(example2));
	printf("%u\n", (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2));

	return 0;
}

    今天須要仔細的總結一下內存對齊機制了,參考了http://www.cnblogs.com/clover-toeic/p/3853132.html的博文。html

首先須要牢記對其準則:linux

①數據類型自身的對齊值,例如char自身對齊值爲1字節,int爲4字節數據結構

②結構體或類的自身對齊值,其成員中自身對齊值最大的那個值函數

③制定對齊值,#pragma pack(value)時制定對齊值spa

④數據成員,結構體和類的有效對齊值,爲其中自身對齊值和指定對齊值中較小者,即有效對齊值。code

其中,有效對齊值N是最終用來決定數據存放地址方式的值。有效對齊N表示「對齊在N上」,即該數據的「存放起始地址%N=0」。而數據結構中的數據變量都是按定義的前後順序存放。第一個數據變量的起始地址就是數據結構的起始地址。結構體的成員變量要對齊存放,結構體自己也要根據自身的有效對齊值圓整(即結構體成員變量佔用總長度爲結構體有效對齊值的整數倍)。htm

字節數規定:blog

①sizeof(short int)<=sizeof(int)內存

②sizeof(int)<=sizeof(long int)get

③short int至少應爲16位(2字節)

④long int至少應爲32位。

由此開始分析這個題目的解答:

    從#include看起,包含了stdio.h頭文件。同時用預處理命令使③制定的自身對齊值爲8,

    從main函數開始分析,首先聲明瞭一個example2結構體,而後打印example1,example2結構體的佔用字節空間大小,最後打印example2結構體中,example1結構體的地址減去example2結構體地址的值。

   main函數很簡單,而後來看example1結構體。結構體包含short和long,因爲32位機器short2字節,long4字節,因此結構體最大自身對齊值爲4,此時內存分配爲short 2,填充 2,long 4,總共佔用8字節。

    example2結構體中example1結構體最大對齊值爲4,char爲1,short爲2,預處理定義爲8,因此仍是按照4字節對齊,此時內存分配爲char 1,填充 3,example1 8,short 2,填充 2,總共佔用16字節

    因爲建立的堆棧是在堆上分配的,堆地址是遞增的,假設example2的初始地址爲x,而後char和填充字節佔了4字節,而後就是example1結構體了,so,(unsigned int)(&struct2.struct1) - (unsigned int)(&struct2)爲(x+4)-x = 4。

本次驗證採用了visual studio,本機電腦爲linux,等到週三考完試把visual studio 截圖拷上去

deepin 15.3  64驗證結果以下:

相關文章
相關標籤/搜索