规则1:以多少个字节为单位开辟内存
就是说,该结构体最终所占字节大小,是这个单位的整数倍
给结构体变量分配内存的时候,会去结构体变量中找基本类型的成员
哪个基本类型的成员占字节数多,就以它大大小为单位开辟内存
在gcc中出现了double类型的例外
(1):成员中只有char型数据 ,以1字节为单位开辟内存。
(2):成员中出现了short 类型数据,没有更大字节数的基本类型数据。 以2字节为单位开辟内存
(3):出现了int 、float 没有更大字节的基本类型数据的时候以4字节为单位开辟内存。
(4):出现了double类型的数据
情况1:
在vc里,以8字节为单位开辟内存。
情况2:
在gcc里,以4字节为单位开辟内存
无论是那种环境,double型变量,占8字节。
(5):如果在结构体中出现了数组,数组可以看成多个变量的集合。
如果出现指针的话,没有占字节数更大的类型的,以4字节为单位开辟内存。
(6):在内存中存储结构体成员的时候,按定义的结构体成员的顺序存储。
规则2:字节对齐
所谓的起始内存单元,是结构体内该元素,相对结构体首地址的位置。
代码验证:
typedef struct user{
char c;
short s;
int a;
}user;
user *u1 =(user*)malloc(sizeof(user));
printf("u1- %p\n char -%p\n short -%p\n int -%p\n",u1,&(u1->c),&(u1->s),&(u1->a));
结果:
(1):char
1字节对齐 ,即存放char型的变量,起始内存单元的编号是1的倍数即可。
(2):short
2字节对齐 ,即存放short int 型的变量,起始内存单元的编号是2的倍
数即可。
(3):int
4字节对齐 ,即存放int 型的变量,起始内存单元的编号是4的倍数即
可
(4):long 在32位平台下,4字节对齐 ,即存放long int 型的变量,
起始内存单元的编号是4的倍数即可
(5):float
4字节对齐 ,即存放float 型的变量,起始内存单元的编号是4的倍数即
可
(6):double
a.vc环境下
8字节对齐,即存放double型变量的起始地址,必须是8的倍数,double变量
占8字节
b.gcc环境下
4字节对齐,即存放double型变量的起始地址,必须是4的倍数,double变量
占8字节。
注意:
当结构体成员中出现数组的时候,可以看成多个变量。
开辟内存的时候,从上向下依次按成员在结构体中的位置顺序开辟空间
struct stu{
int num;
int age;
}lucy;
8字节
struct stu{
char sex;
int age;
}lucy;
8字节
struct stu{
char a;
short int b;
int c;
}temp;
8字节
struct stu{
char a;
int c;
short int b;
}temp;
12字节
struct stu{
char buf[10];
int a;
}temp;
16字节
struct stu{
char a;
double b;
};
12字节
为什么要有字节对齐?
用空间来换时间,提高cpu读取数据的效率