32位编译器:32位系统下指针占用4字节
char:1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
shortint :2个字节
int: 4个字节
unsigned int: 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
longlong: 8个字节
unsigned long: 4个字节
64位编译器:64位系统下指针占用8字节
char:1个字节
char*(即指针变量): 8个字节
shortint :2个字节
int: 4个字节
unsigned int: 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
longlong: 8个字节
unsigned long: 8个字节
字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;例如上面第二个结构体变量的地址空间。
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
4)结构体作为数据成员的对齐规则:在一个struct中包含另一个struct,内部struct应该以它的最大数据成员大小的整数倍开始存储
64位编译器:
Example1:
structA{
longa1;
short a2;
inta3;
int*a4;
};
内存大小:sizeof(A)=8+((2+4)+2)+8 =24
注:括号部分填充2个字节对齐
Example2:
struct B
{
char a;
double b;
int c;
}; 内存大小:sizeof(B) = (1+7) + 8+ (4+4) = 24, 注:前部分填充7个字节补齐,后面填充4个字节补齐
Example3:
struct C
{
int a,
A b,
char c,
};
内存大小:sizeof(C) = (4+4) + 24 + (1+7) = 40, 注:前部分填充4个字节补齐,后面填充7个字节补齐