虚拟机和gcc版本
因为此结论可能和ubuntu和编译器的版本有关,所以先说明一下。
ubuntu版本如下:
gcc版本如下:
测试例程及结论
基本类型结构体
由基本类型组成的结构体的所占空间的大小判断比较简单。所以没做过多测试。测试过程如下。
测试
typedef struct
{
int a;
char b;
short c;
}a_t;
sizeof(a_t) = 8
//*********************************************
typedef struct
{
char a;
short b;
char c;
}b_t;
sizeof(b_t) = 6
//*********************************************
typedef struct
{
short a;
int b;
double c;
}c_t;
sizeof(c_t) = 16
//*********************************************
typedef struct
{
short a;
int b;
char c;
short d;
int e;
}d_t;
sizeof(d_t) = 16
计算方法
首先, 结构体中的数据,会严格按照顺序来存储,不会按照所占内存最小的方式存储。
其次, 结构体中对其的字节数,就是结构体中占内存最大的数据类型所占的内存大小。
计算所占字节数的时候,只需要将内存看成 字节对齐数 大小的盒子。然后想盒子里放东西就好了。
如:
typedef struct
{
short a;
int b;
char c;
short d;
int e;
}d_t;
上述结构体中,最大的数据类型是int,所以字节对齐数为 4,所以,此时就要将内存看成4个字节大小的盒子。
首先,放入一个 a ,也就是short类型,占2个字节。
接下来的 b 是int类型,占4个字节,第一个盒子放不下了,就要开辟第二个盒子。
将 b 放入第二个盒子。因为结构体需要按照顺序存储,所以个第一个盒子剩下的部分只能空下。
第二个盒子满后,要开辟第三个盒子。将 c 放入第三个盒子。
由于第三个盒子里只有一个字节,而 d 是两个字节,能够放得下。所以 d 就被放到了第三个盒子中。
最后,因为第三个盒子只剩1个字节的空间,放不下四个字节的 e ,所以,e 需要放在第四个盒子中。
至此,结构体 d_t 所占的内存数就知道了,是4个盒子,也就是 4 * 4 共16个。
结构体嵌套
结构体嵌套的测试过程较为复杂,就不贴了。直接说计算方法吧。
首先需要确定字节对齐数
外结构体的字节对齐数要取 内结构体 和 外结构体 中最大的数据类型来确定。
内结构体的字节对齐数只取 内结构体 中的数据类型来确定。
示例1:
struct a{
char *a1[3];
}
struct b{
struct a b1;
char b2;
int b3;
}
内结构体 b1 中最大的数据类型为char类型,则 b1 的字节对齐数为1。
外结构体 b 中,最大数据类型为int类型,则 b 则字节对齐数为4。
示例2:
struct a{
int a1;
char a2;
}
struct b{
struct a b1;
short b2;
}
内结构体 b1 中最大的数据类型为int类型,则的字节对齐数为4。
外结构体 b 中,最大数据类型为 b1 中的int类型,则b则字节对齐数为4。
确定字节对齐数后就可以计算占字节大小了
首先按照 基本类型方式 计算子结构体的类型大小。
然后将子结构体作为一个整体,再按照 基本类型的方式 计算外结构体所占字节数。
示例1:
struct a{
char *a1[3];
}
struct b{
struct a b1;
char b2;
int b3;
}
上述代码中,b1 结构体字节对齐数为1,所以 b1 结构体占3个字节。
然后,由于 b 结构体的字节对齐数为4,所以第一个盒子中,放了 b1 后还可以将 b2 放进去
最后将 b3 放进去,所以 b 结构体共占8个字节
示例2:
struct a{
int a1;
char a2;
}
struct b{
struct a b1;
short b2;
}
在上述代码中,由于 b1 的字节对齐数为4,所以 b1 结构体占8字节。
b1 结构体中的 a2 成员后会有填补的空位置。
然后因为 b 结构体的字节对齐数为4,所以 b2 也占4个字节。
最后,b 结构体占12字节。