结构体, enum, union 内存对齐
1 概念
(1) struct结构体变量大小等于结构体中的各个成员变量所占内存大小总和。
(2) union共用体变量大小等于共用体结构中占用内存最大的成员的内存大小。
(3) enum枚举类型(4个字节),指一个被命名的整型常数的集合。即枚举类型,本质上是一组常数的集合体,只是这些常数有各自的命名。枚举类型,是一种用户自定义数据类型。
枚举变量,由枚举类型定义的变量。枚举变量的大小,即枚举类型所占内存的大小。由于枚举变量的赋值,一次只能存放枚举结构中的某个常数。所以枚举变量的大小,实质是常数所占内存空间的大小(常数为int类型,当前主流的编译器中一般是32位机器和64位机器中int型都是4个字节),枚举类型所占内存大小也是这样。
结构体如果含有其他用户自定义类型,相当于所有数据展开,找基本类型中占字节数最多的那个和gcc默认对齐字节(#pragma pack(n))比较,较小者为对齐字节
2 分析
(1) 代码,对齐字节为 int类型占用 4 个字节
#include <iostream>
using namespace std;
class A
{
int i;
char c;
int j;
char d;
union U
{
char buff[11];
int i;
}u;
void foo() { }
typedef char* (*f)(void*);
enum{red, green, blue} color;
}a;
int main(void)
{
cout << sizeof(a);
return 0;
}
运行结果为 32
具体分析:
总的有效对齐为 4 个字节
offset, 该变量到开始0的偏移位置
int i // 占用 0 - 3, 整型大小为4字节, 等于对齐字节4,
// 所以offset应该为4的倍数, 0符合
char c // 占用 4, 字符大小为1字节,小于对齐字节4,
// 所以offset应该为1的倍数, 下一位是4, 符合要求
int j // 占用 8 - 11, 整型大小为4字节,等于对齐字节
// 所以offset应该为4的倍数,下一位是5, 不符合要求, 最接近的是8, 所以从8开始
char d // 占用 12, 字符大小为1字节,小于对齐字节4,
// 所以offset应该为1的倍数, 下一位是12, 符合要求
union u // 占用 16 - 26, union 的基本类型最大int为4字节,等于对齐字节4,
// 所以offset应该为4的倍数, 下一位是13, 不符合要求, 最接近的是16, 所以从16开始
void foo() // 函数不占用
typedef char* (*f)(void*) // 不占用
enum color // 占用 28-31, enum 的基本类型是 int 为4字节, 等于对齐字节4,
// 所以offset应该为4的倍数, 下一位是27, 不符合要求, 最接近的是28, 所以从28开始
(2) 代码,对齐字节为 long类型占用 8 个字节
#include <iostream>
using namespace std;
class A
{
int i;
char c;
int j;
char d;
union U
{
char buff[11];
long i;
}u;
void foo() { }
typedef char* (*f)(void*);
enum{red, green, blue} color;
}a;
int main(void)
{
cout << sizeof(a);
return 0;
}
运行结果为 40
还没有评论,来说两句吧...