关于结构体所占内存大小
关于结构体内存大小问题
我们首先要了解一个相关概念————偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。
struct book {
int num1;
char c1;
}book1;
假定我们定义一个结构体book1,第一个成员变量num1,此时num1的偏移量为0(因为此刻的num1地址为该结构体所占内存空间的首地址,所以两者之间的差为0),此刻所使用的内存空间是(0+4)(偏移量+该变量的字节大小),第二个成员变量为c1,偏移量为前面变量的偏移量之和为4。而此时的通过sizeof输出的结果却不是5(4+1,偏移量+该变量的字节大),是为什么呢?
在实际中,存储变量时地址要求对齐,编译器在编译程序时会遵循两条原则:
- 结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
- 结构体大小必须是所有成员大小的整数倍,也即所有成员大小的公倍数。
在我们刚才所定义的结构体book1中,我们所认为的结果是5,但是在该对齐规则中,5并不是int所占字节的倍数,因此会在变量c1后面补上3个字节的空间。
后面为补上的3个字节大小的空间。因此通过关键字sizeof输出的结果为8。
结构体成员不同的排序方式,导致的结构不同。
比如下面的代码:
#include<stdio.h>
struct book {
int num1;
char c1;
char c2;
}book1;
int main(int argc,char *argv[]){
printf("%d",sizeof book1);
return 0;
}
通过上面的偏移量概念和对齐规则我们得出的结果为8。第一个成员变量num1的偏移量为0,第二个成员变量c1的偏移量为4,第三个成员c2变量的偏移量为(4+1),最后所占内存大小等于c2偏移量加上c2的字节大小等于6(4+1+1),再按照对齐规则,该结构体成员变量中字节最大为int型,所以后面再补上2个字节为8,能被4整除。
#include<stdio.h>
struct book {
char c1;
int num1;
char c2;
}book1;
int main(int argc,char *argv[]){
printf("%d",sizeof book1);
return 0;
}
通过调换第一和第二个成员变量的顺序,我们发现通过关键字sizeof输出的数值大小为12。第一个成员变量c1的偏移量为0,第二个成员变量num1的偏移量似乎为1,不同于上面的是此刻的偏移量1不是int型所占字节的倍数。所以char c1后面需要补上三个字节,因此第二个成员num的偏移量是4。第三个成员变量c2的偏移量为8,最后所占的大小是(1+4+3+1)9,9不是4的倍数,后面再补上3个字节大小,成为int型变量所占字节大小的倍数。
#include<stdio.h>
struct node
{
char a[5];
int b;
char c;
int d;
}tree;
int main(int argc, char const *argv[])
{
printf("%d\n",sizeof tree);
return 0;
}
结果输出是20;
2022 7.17 补充:
#include <stdio.h>
typedef struct
{
char a;
int b;
short c;
char d;
}NODE;
int main(int argc, char const *argv[])
{
printf("%d\n",sizeof(NODE));
return 0;
}
发现了另一种更容易明白的画图方法供大家理解:
这样的输出结果是12。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)