#include <stdio.h>
#if 1
typedef struct MyStruct
{
double dda0;
char dda1;
short dda3;
double dda4;
int type ;
}testS;
char *p;
char *q[20];
char *m[20][20];
int (*n)[10];
testS k;
#define TITLE() printf("%-20s" " %-10s/n", "Data Type", "Data Size")
#define PRINTSIZE(type) printf("%-20s"": %-10d/n", #type,sizeof(type))
void main(void)
{
TITLE();
memset(&k, 0, sizeof(testS));
PRINTSIZE(int);
PRINTSIZE(char);
PRINTSIZE(short);
PRINTSIZE(long);
PRINTSIZE(double);
PRINTSIZE(float);
PRINTSIZE(long int);
PRINTSIZE(long double);
PRINTSIZE(long float);
PRINTSIZE(p);
PRINTSIZE(q);
PRINTSIZE(m);
PRINTSIZE(n);
PRINTSIZE(k);
}
#endif
該程式在我的機器(32位,P4)上的運行結果如下:
Data Type Data Size
int : 4
char : 1
short : 2
long : 4
double : 8
float : 4
long int : 4
long double : 8
long float : 8
p : 4
q : 80
m : 1600
n : 4
k : 32
Press any key to continue
我們看到了這個結果, 其中有一項
k : 32
說明struct MyStruct的大小是32bytes.
有些人會認為應該是24才對.
下面我們來分析一下為什麼會是32:
首先我來看以下結構:
typedef struct MyStruct
{
double dda0;
char dda1;
short dda3;
double dda4;
int type ;
}testS;
double類型佔8bytes,這個是沒有問題的了 , 接下來 char類型佔1byte,short類型佔2bytes,int類型佔4bytes,
我們常認為在32位機上記憶體的對齊是4bytes(32位)對齊。使用我們認為的dda1和dda2佔4bytes, 這樣算下來就是8+4+8+4=24.
但是在這裡不是這樣的了,在這個結構裡有double 類型,它是一個c的基本類型,在這裡記憶體的對齊是8bytes。這是因為
struct中的各成員變數的儲存地址有一套對齊的機制。這個機制概括起來有兩點:第一,每個成員變數的首地址,必須是它的類型的對齊值的整數倍,如果不滿足,它與前一個成員變數之間要填充(padding)一些無意義的位元組來滿足;第二,整個struct的大小,必須是該struct中所有成員的類型中對齊值最大者的整數倍,如果不滿足,在最後一個成員後面填充。
所以testS的大小是8+8+8+8=32