C语言 结构体 所占内存 计算方式详解(没有对字节对齐进行解释)-CSDN博客

90 阅读4分钟

目录

虚拟机和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字节。