C語言結構體大家都不陌生,本文講解結構體在內存空間中的分配情況。
直接上驗證代碼(VS2010):
#include <stdio.h>
typedef struct
{
char a;
short b;
int c;
}test_t1;
typedef struct
{
int a;
short b;
char c;
}test_t2;
typedef struct
{
short a;
char b;
int c;
}test_t3;
typedef struct
{
short a;
int b;
char c;
}test_t4;
void main()
{
test_t1 test1;
test_t2 test2;
test_t3 test3;
test_t4 test4;
printf("sizeof(char) :%d\r\n",sizeof(char));
printf("sizeof(short):%d\r\n",sizeof(short));
printf("sizeof(int) :%d\r\n\r\n",sizeof(int));
printf("sizeof(test1):%d\r\n",sizeof(test1));
printf("sizeof(a):%d\r\n",sizeof(test1.a));
printf("sizeof(b):%d\r\n",sizeof(test1.b));
printf("sizeof(c):%d\r\n",sizeof(test1.c));
printf("&(test1):%4x\r\n",&(test1));
printf("&(a):%4x\r\n",&(test1.a));
printf("&(b):%4x\r\n",&(test1.b));
printf("&(c):%4x\r\n\r\n",&(test1.c));
printf("sizeof(test2):%d\r\n",sizeof(test2));
printf("sizeof(a):%d\r\n",sizeof(test2.a));
printf("sizeof(b):%d\r\n",sizeof(test2.b));
printf("sizeof(c):%d\r\n",sizeof(test2.c));
printf("&(test2):%4x\r\n",&(test2));
printf("&(a):%4x\r\n",&(test2.a));
printf("&(b):%4x\r\n",&(test2.b));
printf("&(c):%4x\r\n\r\n",&(test2.c));
printf("sizeof(test3):%d\r\n",sizeof(test3));
printf("sizeof(a):%d\r\n",sizeof(test3.a));
printf("sizeof(b):%d\r\n",sizeof(test3.b));
printf("sizeof(c):%d\r\n",sizeof(test3.c));
printf("&(test3):%4x\r\n",&(test3));
printf("&(a):%4x\r\n",&(test3.a));
printf("&(b):%4x\r\n",&(test3.b));
printf("&(c):%4x\r\n\r\n",&(test3.c));
printf("sizeof(test4):%d\r\n",sizeof(test4));
printf("sizeof(a):%d\r\n",sizeof(test4.a));
printf("sizeof(b):%d\r\n",sizeof(test4.b));
printf("sizeof(c):%d\r\n",sizeof(test4.c));
printf("&(test4):%4x\r\n",&(test4));
printf("&(a):%4x\r\n",&(test4.a));
printf("&(b):%4x\r\n",&(test4.b));
printf("&(c):%4x\r\n\r\n",&(test4.c));
}
輸出結果:
結論:
- 默認情況下,結構體的大小是結構體中最長類型的整數倍。
- 結構體中的空間分佈是按照結構體中最長類型對齊的。
- 結構體中不同類型的成員,一定是按照自己的類型對齊。比如,int型的起始地址一定是4的整數倍,short型的首地址一定是2的整數倍。。。
用上面的例子說明結論。
情況1:
typedef struct
{
char a;
short b;
int c;
}test_t1;
在內存中空間分佈(根據上面示例實際分配空間):(a的大小本身是1字節,但是內存爲他分配了2字節空間)
情況2:
typedef struct
{
int a;
short b;
char c;
}test_t2;
在內存中空間分佈(根據上面示例實際分配空間):(c的大小本身是1字節,但是內存爲他分配了2字節空間)
情況3:
typedef struct
{
short a;
char b;
int c;
}test_t3;
在內存中空間分佈(根據上面示例實際分配空間):(b的大小本身是1字節,但是內存爲他分配了2字節空間)
情況4:
typedef struct
{
short a;
int b;
char c;
}test_t4;
在內存中空間分佈(根據上面示例實際分配空間):(a的大小本身是2字節,但是內存爲他分配了4字節空間;c的大小本身是1字節,但是內存爲他分配了4字節空間)
看明白了嗎?結構體分配空間時,是順序分配的,當分配到某一成員時,如果分配的地址沒有按照該成員的類型對齊,那麼往後找,直到找到按該成員類型對齊的地址。
再舉例說明:
情況5:
typedef struct
{
int a;
long long b;
char c;
char d[6];
}test_t6;
上面的結構體分配空間如下:
longlong型在VS2010中佔8字節,所以該結構體一共佔24字節。實際輸出驗證下:
可以看到實際結果與理論一致。
再舉一例:
情況6:
typedef struct
{
char a;
char b;
int c;
char d;
char e;
short f;
}test_t7;
上面的結構體分配空間如下:
該結構體一共佔12字節。實際輸出驗證下:
可以看到實際結果與理論一致。
這種結構體對齊是默認情況下的對齊。實際使用中可以指定對齊方式,也可以按照字節對齊、2字節對齊方式。這個放在下一篇討論。