struct A { char a1; short a2; int a4; char *p1; };
这么个结构体,如何计算它在内存里占用的大小?
这里涉及到的就是计算机内部数据存储原则,需要对齐,若是按常规的64位机器:char型=1Byte,short =2Byte,int=4Byte,指针8Byte 最后结果相加1+2+4+8=15 那么就错了
三个原则:
原则1、数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。
原则2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)
原则3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
按照这三个原则计算一遍:
char=1Byte 内存地址若为0
short=2Byte 按原则一,此时内存1的位置还没有数据,可它需要从2的倍数开始存储,所以它开始地址在2
int=4Byte 按原则一,此时刚好到地址4没有数据,那么就从地址4开始占据4个字节
指针=8Byte 按原则一要从地址为8的位置开始,刚好到地址8还没有数据,所以,从8开始占据8个字节
最后看是否满足其他原则,这里没有结构体成员,所以只看原则三了,最后的内存总数为1+1个空闲+2+4+8=16 ,其中最大的指针的内存8Byte,16是8的倍数,所以满足该原则。
用一个图更好理解:
看到其中白色部分是为了满足原则一而空闲出来的部分,所以最后该结构体的大小为16Byte。
改换一下结构体内的顺序:
struct A { char a1; int a4; short a2; char *p1; };
将与short的顺序变换了一下,其他都一样:
同样三原则走下去:
char=1Byte 内存: 0
int=4Bytr 但从内存4开始计算 内存 : 4-7
short=2Byte 从内存8开始 内存: 8-9
*p指针=8Byte 需要从内存16开始 内存:内存:16-23
最后占据24个字节,是8的倍数,所以结构体占据24个字节。载配合图片好好理解一下,白色是为满足对齐原则消耗的内存
测试程序包含一些其他类型的内存计算:
struct A { char a1; int a4; short a2; char *p1; }; int main() { struct A a; char b[30]; char* c = (char*)malloc(sizeof(char*)*10); printf("%d ", sizeof(a)); printf("%d ", sizeof(b)); printf("%d ", sizeof(b[3])); printf("%d ", sizeof(c)); printf("%d ", sizeof(*(c + 3))); }