结构体内存对齐,默认对齐数,结构体传参
我們先來計算一下結構體內存的大小
?現在我們計算一下stu1和stu2每個成員內存偏移是多少。
在介紹偏移量之前,我們先簡單介紹一下offsetof(是一個宏),它是用來計算結構體成員相較于起始位置的偏移量。
?現在我們來詳細介紹一下內存偏移是怎么回事
?結構體內存對齊規則:
1.結構體的第一個成員直接對齊到相對于結構體變量起始位置為0的偏移處。
2.從第二個成員開始,要對齊到某個【對齊數】的整數倍的偏移處。
對齊數:結構體成員自身大小和默認對齊數的較小值。
Linux環境默認不設置對齊數(對齊數是結構體成員的自身大小)。
vs:默認對齊數8.
3.結構體總大小,必須是最大對齊數的整數倍。
每個結構體成員都有一個對齊數,其中最大的對齊數就是最大對齊數。
4.如果嵌套了結構體的情況
嵌套的結構體對齊到自己的最大對齊數的整數倍處。
結構體的整數大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍。
(這就是為什么雖然stu1和stu2的結構體成員變量雖然相同,但是因為成員變量順序不同,根據對齊規則,所占內存大小也不相同)
為什么存在結構體內存對齊?
平臺原因:
不是所有硬件平臺都能訪問任意地址上的任意數據,某些硬件平臺只能在某些地址處取某些特定類型的數據,否則會拋出硬件異常。
性能原因:
數據結構(尤其是棧)應該盡可能在自然邊界上對齊。
原因在于,為了訪問為對齊的內存,處理器需要作兩次內存訪問;而對齊的內存訪問僅需要一次訪問。
總體來說:
結構體內存對齊就是用空間換取時間的做法。(如果想要既滿足對齊,又節省空間,那就要讓占用空間小的成員盡量集中在一起)
默認對齊數:
默認對齊數可以自己設置的。
舉個例子?
結構體傳參:
#include<stdio.h> struct stu1 {int date[20];int num; }; void print1(struct stu1 S) {printf("%d %d %d\n", S.date[1],S.date[2], S.num); } void print2(struct stu1*p) {printf("%d %d %d\n", (*p).date[1],(*p).date[2], (*p).num);printf("%d %d %d\n", p->date[1], p->date[2], p->num); } int main() {struct stu1 S1 = { {1,2,3,4},20 };print1(S1);print2(&S1);return 0; }輸出結果是一樣的,那么這兩種方式選擇哪一種比較好呢,答案是第二種。
我們知道形參是實參的臨時拷貝,采用第一種方式,print1函數需要開辟一部分空間給形參,用來存放實參傳遞的函數,這樣內存消耗較多。采用第二種方式不需要開辟新的內存空間,print2函數只需要開辟一個4字節或者8字節的內存去存放傳遞過來的指針大小即可,再根據這個指針指向即可找到需要使用的數據,這樣內存空間消耗相對于print1方法來說小很多。
總結
以上是生活随笔為你收集整理的结构体内存对齐,默认对齐数,结构体传参的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SSL数字证书(一)CA、根证书与数字证
- 下一篇: Windows IIS服务器SSL数字证