C++中結構體的sizeof
- 為什麼要地址對齊?
- * 我們在訪問記憶體時,如果地址是按4位元組對齊,則訪問效率會高很多。
- * 這個問題的原因在於訪問記憶體的硬體電路。一般情況下,地址匯流排總是按照對齊後的地址來訪問。
- * 例如你想得到0x00000001開始的4位元組內容,系統首先需要以0x00000000讀4位元組,
- * 然後從中取得3位元組,然後在用0x00000004作為開始地址,獲得下一個四位元組,
- * 在從中得到第一個位元組,兩次組合出你想得到的內容。但是如果地址一開始就是對齊到
- * 0x00000000,則系統只要一次讀寫即可。
- 所以,為了效能考慮,編譯器會做地址對齊。
- 地址對齊的原則:
- 每個基本型別有自己預設的對齊值。 然後可以通過#pragma pack(2)設定編譯器的預設對齊值。取兩者最小的一個作為最終對齊值。
- 若沒有#pragma pack(2)設定,那麼只看基本型別自己的對齊值。
- 總之: 在允許的情況下,儘量依次填充,但是需要保證(32位系統)
- 1 char,bool只從X地址處開始儲存;
- 2 short只從2X地址出開始儲存;
- 3 int,float,long只從4X地址處開始儲存;
- 4double只從8X地址處開始儲存;
下面是列子:
#include <iostream>
using namespace std;
//sizeof(union1) = 16
union union1 {
long i; //4
int x[4]; //16
char ch; //1
};
//sizeof(union2) = 16
union union2{
char a[13];
int i; //由於int的存在,使得union按照四個位元組來對其了
};
//sizeof(union3) = 13
union union3{
char a[13];
char i;
};
/////////////// 對比node1和node2 ///////////
struct node1{ //24
int j; //4
double f; //8
int i; //4
};
struct node2{ //16
int i; //4
int j; //4
double f; //8
};
/////////////// 對比node3和node4 ///////////
struct node3{ //32(注意)
char i; //1
int d[5]; //20
double f; //8
};
struct node4{ //40
int d[5]; //20
double f; //8
int i; //4
};
///////////////////////////////////////////
struct node5{ //32(注意)
char d[10]; //10
double f; //8
int i; //4
};
struct node6{ //20
char d; //1
int f; //4
char i[10]; //10
};
//}__attribute__((aligned (1)));
///////////////////////////////////////
struct node7{ //12
char x1; //1
short x2; //2
float x3; //4
char x4; //4
};
#pragma pack(1) //指定按照1位元組對齊
struct node8{ //8
char x1; //1
short x2; //2
float x3; //4
char x4; //1
};
#pragma pack() //恢復預設的位元組對齊設定
////////////////////////////////////////
struct node9{ //20
char ch,*p; //1,4
union{ //4
short a,b;
unsigned int c:2,d:1;
}u;
bool f; //1
struct node9 *next; //4
};
//測試位元組對齊
void test2(){
int size;
struct node1 n1;
struct node2 n2;
struct node3 n3;
struct node4 n4;
struct node5 n5;
struct node6 n6;
struct node7 n7;
struct node8 n8;
struct node9 n9;
//棧生長的方向與地址增長方向相反,所以a的地址比b的地址大四位元組
int a = 1,b = 2,c=3;
int *p = &b;
printf("%d\n",*(p+1)); //1
//測試union和struct的大小(後者會地址對齊,前者仍然輸出16)
printf("union1:%d\n",sizeof(union union1)); //16
printf("union2:%d\n",sizeof(union union2)); //16
printf("union3:%d\n",sizeof(union union3)); //13
//測試結構體的地址對齊
printf("************************\n");
printf("n1:%d\n",sizeof(n1));
printf("%ld\n",(unsigned long)&n1.j);
printf("%ld\n",(unsigned long)&n1.f);
printf("%ld\n",(unsigned long)&n1.i);
printf("************************\n");
printf("n2:%d\n",sizeof(n2));
printf("%ld\n",(unsigned long)&n2.i);
printf("%ld\n",(unsigned long)&n2.j);
printf("%ld\n",(unsigned long)&n2.f);
printf("************************\n");
printf("n3:%d\n",sizeof(n3));
printf("%ld\n",(unsigned long)&n3.i);
printf("%ld\n",(unsigned long)&n3.d);
printf("%ld\n",(unsigned long)&n3.f);
printf("************************\n");
printf("n4:%d\n",sizeof(n4));
printf("%ld\n",(unsigned long)&n4.d);
printf("%ld\n",(unsigned long)&n4.f);
printf("%ld\n",(unsigned long)&n4.i);
printf("************************\n");
printf("n5:%d\n",sizeof(n5));
printf("%ld\n",(unsigned long)&n5.d);
printf("%ld\n",(unsigned long)&n5.f);
printf("%ld\n",(unsigned long)&n5.i);
printf("************************\n");
printf("n6:%d\n",sizeof(n6));
printf("%ld\n",(unsigned long)&n6.d);
printf("%ld\n",(unsigned long)&n6.f);
printf("%ld\n",(unsigned long)&n6.i);
printf("************************\n");
printf("n7:%d\n",sizeof(n7));
printf("%ld\n",(unsigned long)&n7.x1);
printf("%ld\n",(unsigned long)&n7.x2);
printf("%ld\n",(unsigned long)&n7.x3);
printf("%ld\n",(unsigned long)&n7.x4);
printf("************************\n");
printf("n8:%d\n",sizeof(n8));
printf("%ld\n",(unsigned long)&n8.x1);
printf("%ld\n",(unsigned long)&n8.x2);
printf("%ld\n",(unsigned long)&n8.x3);
printf("%ld\n",(unsigned long)&n8.x4);
printf("************************\n");
printf("n9:%d\n",sizeof(n9));
}
int main(){
int *ptr;
test2();
printf("************************\n");
printf("char:%d\n",sizeof(char)); //1
printf("short:%d\n",sizeof(short)); //2
printf("int:%d\n",sizeof(int)); //4
printf("long:%d\n",sizeof(long)); //4
printf("float:%d\n",sizeof(float)); //4
printf("double:%d\n",sizeof(double)); //8
printf("pointer:%d\n",sizeof(ptr)); //4
return 0;
}
相關文章
- C++結構體內幕揭秘:sizeof之謎與記憶體佈局探秘C++結構體記憶體
- sizeof()的結果值
- C++中的結構體初始化的多種方式C++結構體
- C++中的選擇結構C++
- C++中的迴圈結構C++
- C++語法-結構體C++結構體
- C++ - 結構體轉cha*C++結構體
- 【c++】結構體sort排序C++結構體排序
- c++結構體、共用體(聯合體)C++結構體
- C++中結構體是使用例項還是指標C++結構體指標
- C++ struct結構體記憶體對齊C++Struct結構體記憶體
- Runtime中的 isa 結構體結構體
- C/C++結構體對齊測試C++結構體
- java中serverlet的體系結構JavaServer
- C 結構體中的位域概念結構體
- C++資料結構和pb資料結構的轉換C++資料結構
- 理解sizeof
- 以下為Windows NT 下的32 位C++程式,請計算sizeof 的值WindowsC++
- C++資料結構連結串列的基本操作C++資料結構
- C\C++之用結構體實現連結串列的建立、遍歷、結點插入、結點刪除C++結構體
- 結構體中套用其他_結構體結構體
- 結構體的大小結構體
- C++ 專案目錄結構C++
- c++基本資料結構C++資料結構
- C# 中的只讀結構體(readonly struct)C#結構體Struct
- InfluxDB中的inmem記憶體索引結構解析UX記憶體索引
- 資料結構——單連結串列的C++實現資料結構C++
- C++讀取txt檔案,並將每一行的資訊存入結構體陣列中C++結構體陣列
- JAVA使用SizeOfJava
- JavaScript中的程式結構和分支結構JavaScript
- libev中ev_loop結構體中巨集定義的理解OOP結構體
- 解析C語言中的sizeofC語言
- sizeof與strlen的區別
- 結構體結構體
- 關於sizeof,對空指標sizeof(*p)可以嗎?指標
- C# 中 System.Range 結構體C#結構體
- C++資料結構-佇列C++資料結構佇列
- c++基礎十(流程結構)C++
- 資料結構之堆(c++)資料結構C++