既然你打开了这篇文章,那么就相信你也是想清楚的了解一下内存对齐的问题,现在也是有大厂会面试到这道题的。
首先请允许我引入这一问题,我们先看看下面这段代码:
#include<stdio.h>
struct t1
{
char name[3];
int a;
double b;
};
struct t2
{
char name[3];
double b;
int a;
};
int main()
{
struct t1 p1;
printf("t1=%d\n", sizeof(p1));//输出16
struct t2 p2;
printf("t2=%d\n", sizeof(p2));//输出24
system("pause");
return 0;
}
他的输出结果如下:
那么为什么结构体内部的变量明明是一样的,却占用的内存去不一样呢。这里就涉及到了结构体内部的内存对齐操作,那么怎么计算一个结构体所占用的内存呢。首先我们先了解以下几个概念
1.所谓的内存对齐就是结构体内的每一个变量都要按照结构体内变量内存最大的类型的内存对齐,这里要注意一点,字符数组的大小类型还是1,不会因为字符数组的长度最大而以这个长度来作为内存对齐的最大长度。
2.当char型和int型处于相邻的位置时,在一定的程度上,可以把两者结合在一起。一般在出现内存对齐长度为8位的时候,就可以根据需求把两者看作在一起。
3.结构体内部为同种类型的变量时,直接相加即可。
明白以上三点后,在看下面的代码就很清晰了。
#include<stdio.h>
struct t1
{
char a1[2];
char a2[3];
int a3;//这里的char类型和int类型在一起,并且对齐内存为8,所以可以看作一起。故2+3+4=9,在补齐为8的倍数,则为16
double a4;//这里以double作为对齐内存
//最终结果为8+16=24
};
struct t2
{
char name[3];//这里的char没有可以组合的,故只能自己补齐到8位
double b;//这里以double作为对齐内存
int a;//这里的int没有可以组合的,故只能自己补齐到8位
最终结果为8+8+8=24
};
struct t3
{
char a1[3];
char a2[2];
char a3[4];
char a4;
//这里的类型全部相同,故直接相加即可结果为3+2+4+1=10
};
struct t4
{
int* a1;//操作系统是32位的,所以指针类型占用4个字节
char* a2;//也是四个字节,且对齐内存为4个字节
char a3[4];//刚刚好,不需要补
char a4[2];//需要补齐为4
//最终结果为4*4=16
};
struct t5
{
struct t3 p;//这里插入了结构体也没关系,只需要把它的内部变量带入这个里面即可,如下:
/* char a1[3];
char a2[2];
char a3[4];
char a4; */
int a5;//这里的char和int在一起,故可以看作一起,既14,然后补齐到8的倍数即为16
double a6;//这里的double为对齐内存
//最终结果为24
};
union t6//共用体内部也有内存对齐问题
{
char a1[19];//也是补成四的倍数,既补成20
int a2;//这里的int作为最大对齐内存为4
//因为公用体内所有的变量公用一段内存,故共用体的内存为最大变量的内存,所以占用内存为20
};
union t7//共用体内部也有内存对齐问题
{
char a1[19];//这里的对齐内存为8,所以补成8的倍数,既24
double a2;//这里的double作为最大对齐内存为8
//因为公用体内所有的变量公用一段内存,故共用体的内存为最大变量的内存,所以占用内存为24
};
int main()
{
struct t1 p1;
printf("t1=%d\n", sizeof(p1));
struct t2 p2;
printf("t2=%d\n", sizeof(p2));
struct t3 p3;
printf("t3=%d\n", sizeof(p3));
struct t4 p4;
printf("t4=%d\n", sizeof(p4));
struct t5 p5;
printf("t5=%d\n", sizeof(p5));
union t6 p6;
printf("t6=%d\n", sizeof(p6));
union t7 p7;
printf("t7=%d\n", sizeof(p7));
system("pause");
return 0;
}
输出结果如下:
那么学习这个有什么作用呢,实际作用是,在一定程度上可以减少内存空间的浪费,以及数据传输过程中所消耗的流量。
那么怎么使用这中方法,才能使结构体内存尽可能的小呢,只需要在创建结构体变量时,尽可能的按照变量的大小,从小到大,从上到下的方式去创建。
以上就是我个人对结构体和共用体内部如何计算内存的理解了,谢谢你的观看。