前言
前几天有个小朋友问了我一下,关于C语言结构体占用空间的问题。觉得以后会对小可爱有点帮助,就打算先写一下。
struct Test
{
int a;
char b;
int c;
} test;
理论上,结构体中的各个成员在内存中应该是连续储存的,就像数组里面的元素一样。事实上,也确实是这个样子的,不过和我们想象的有点不一样。
按照我们最初的想法,变量test所占的内存为 4 + 1 + 4 = 9。
但是我们写一个小代码验证一下发现和我们想的不一样。
它的内存为12。因为 int类型是4个字节,所以是不是各个成员的内存都是按照最大的那个设置呢?毕竟 4 * 3 = 12,我们再次实验,
如果按照我们的推测,那么内存大小应该是 8 * 3 = 24。为何是16呢?
下面我来总结一下。
总结
C语言结构体所占内存大小,其实里面涉及到C语言内存对齐,提高寻址效率的一种思想在里面。具体我就不在这里展开来说了,有兴趣的可以自己百度了解一下。
其实小可爱最想了解的应该是如何计算,结构体的内存大小。
不包含,数组和指针的结构体
对于不包含,数组和指针的结构体,知道各个成员所占内存大小后,可以直接相加,不过相加的时候必须保证前面的成员变量的内存所占内存必须是下一个成员变量所占内存的整倍数,如果不够就补上;并且最后的结果必须要是所占内存空间最大的成员变量的整倍数。
下面我来几个例子说明:
struct Test
{
double c; //8
int a;//4
char b;//1
} test;
所占内存大小,8 + 4 + 1 = 13,最大内存为8, 所以应该这样计算 8 + 4 + 4 = 16。
下面我们交换下,
struct Test
{
int a;//4
double c; //8
char b;//1
} test;
所占内存大小, 4 + 8 + 1 = 13,因为double类型是8个字节,而前面只有4个字节,并且成员变量最大内存为8,所以应该这样计算 8 + 8 + 8 = 24。
struct Test
{
int a;//4
char b;//1
double c; //8
} test;
同理4 + 1 + 8 = 13,应该变为 4 + 4 + 8 = 16。
包含,数组和指针的结构体 包含指针的结构体
对于包含指针的结构体,可以用和上面相同的方法进行计算,一般指针的大小都是固定的4个字节(在我的电脑上,你们可能不同),因为不管什么类型的指针只需要储存地址,不需要储存地址指向空间的内容。
struct Test
{
char a;//1
char *b;//4
double c;//8
} test;
struct Test
{
char a;//1
int *b;//4
double c;//8
} test;
struct Test
{
char a;//1
double *b;//4
double c;//8
} test;
这三种所占内存大小均为 4 + 4 + 8 = 16。如果将变量 b 和变量 c 的位置互换,则变为 8 + 8 + 8 = 24。 包含数组的结构体
数组中的元素地址是连续的,所以一个数组所占空间大小,为数组类型 * 元素个数。
知道了数组所占空间大小后,再来说说如何计算结构体中包含数组的情况,在之前计算的时候,我说过相加的时候必须保证前面的成员变量的内存所占内存必须是下一个成员变量所占内存的整倍数,但是如果下一变量为数组,则没有这个要求。
例如:
struct Test
{
int a;
char b[21];
int d;
double c;
} test;
应该为 4 + 24 + 4 + 8 = 40。
struct Test
{
int a;
char b[19];
int d;
double c;
} test;
应该为 4 + 20 + 8 + 8 = 40。
struct Test
{
char a;//1
char b[19];//19
int d;//4
double c;//8
} test;
应该为 1 + 19 + 4 + 8 = 32。
struct Test
{
char a;//1
char b[17];//17
int d;//4
double c;//8
} test;
应该为 1 + 19 + 4 + 8 = 32。
struct Test
{
char a;//1
char b[15];//15
int d;//4
double c;//8
} test;
应该为 1 + 15 + 8 + 8 = 32。
到此这篇关于C语言结构体占用内存的文章就介绍到这了