1.联合体
- 在联合体中,各成员共用同一内存空间,以最大元素为准。
- 当一个联合被说明时,编译程序自动地产生一个变量,其长度为联合中最大的变量长度。
union un
{
char a[17];
int b;
};
在32位机器中,上述联合体u的占用字节数为20。
2.结构体
- 结构体的第一个数据成员放在offset为0的地方,之后所有元素的起始位置都必须是当前元素的整数倍
- 若结构体A 中含有结构体B,则B 的起始位置也必须是B 中最大成员的整数倍
- 结构体的大小必须是最大基本数据类型(char、int、float、double)的整数倍
union un
{
char a[17];
int b;
};
struct data
{
char ch;
short a;
int b;
un c;
double d;
float e[2];
};
int main()
{
data da;
cout << sizeof(un) << endl << sizeof(data) << endl;
cout << &da<< "\t" << &da.a << "\t" << &da.b << "\t" << &da.c << "\t" << &da.d <<"\t" << &da.e << endl;
return 0;
}
在32位机器中,上述结构体data的占用字节数为48。
运行结果为:
在内存空间的分布如下:
图中的红色竖线即代表data结构体中的各元素。
3.指定对齐值
编译器中提供了#pragma pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:
- 如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式。
- 如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。
结构的总大小也有个约束条件,分下面两种情况:
- 如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数
- 否则必须为n的倍数。
#pragma pack(2)
#include <iostream>
using namespace std;
union un
{
char a[5];
int b;
};
struct data
{
char ch;
int a;
un u;
char b;
};
int main()
{
data da;
cout << sizeof(un) << endl << sizeof(data) << endl;
return 0;
}
在32位机器中,上述联合体un 和结构体data 所占的字节数分别为6,14。
4.其他
- 在64位机器中,指针变量所占字节数分别为 8 字节。
- 在C++中, 若一个类含有虚函数,则还要加上虚表指针所占空间。
#include <iostream>
using namespace std;
struct data
{
char ch;
virtual void foo() {}
};
int main()
{
data da;
cout << sizeof(data) << endl;
return 0;
}
在32位机器中,上述data 类对象所占空间为8 字节。