前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >结构体内存对齐

结构体内存对齐

作者头像
用户11328191
发布于 2024-10-23 06:39:17
发布于 2024-10-23 06:39:17
9100
代码可运行
举报
文章被收录于专栏:li_waitli_wait
运行总次数:0
代码可运行

结构体的对齐规则:

1.结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处 2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数与该成员变量大小的较小值。   VS 中默认的值为 8   Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小 3. 结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的 整数倍。 4. 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//练习1
struct S1
{
	char c1;
	int i;
	char c2;
};
printf("%d\n", sizeof(struct S1));//12

 以下以VS分析:

  • char c1:占用1个字节 - 从偏移量为0的地址处开始对齐
  • 填充:3个字节,以确保int i从4的倍数地址开始  - 确保下一个地址的偏移量为4的倍数
  • int i:占用4个字节 - 编译器默认对齐数为8,int类型的大小为4个字节 ,因此该对齐数采用较小的4
  • int i 对齐完后,偏移量为7,下一个偏移量为8,是char类型对齐数的整数倍
  • char c2:占用1个字节  -偏移量为8
  • 到这里结构体占用了9个字节
  • 填充:1个字节,结构体的总大小是最大对齐数的倍数,在这里,最大对齐数为4。结构体目前大小为9,不是4的倍数,填充3个字节,大小为12,是4的整数倍。
  • 所以,struct S1的总大小是1(c1)+ 3(填充)+ 4(i)+ 1(c2)+ 3(填充)= 12字节。

下面给出2个练习,大家动手算算吧。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//练习2
struct S2
{
	char c1;
	char c2;
	int i;
};
printf("%d\n", sizeof(struct S2));//8
//练习3
struct S3
{
	double d;
	char c;
	int i;
};
printf("%d\n", sizeof(struct S3));//16
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//练习4-结构体嵌套问题
struct S4
{
	char c1;
	struct S3 s3;
	double d;
};
printf("%d\n", sizeof(struct S4));//32
  • char c1:占用1个字节 - 从偏移量为0的地址处开始对齐
  • struct S3的最大对齐数为8,因此s3应该从偏移量为8的位置开始对齐
  • 填充:7个字节 -- 确保下一个地址的偏移量为8的倍数
  • struct S3 s3:占用16个字节 
  • struct S3 s3对齐完后,偏移量为23,下一个偏移量为24,是doubler类型对齐数的整数倍
  • double:占用8个字节  -偏移量为31
  • 到这里结构体占用了32字节,结构体的总大小是最大对齐数(含嵌套结构体成员的对齐数)的倍数,在这里,最大对齐数为8。结构体目前大小为32,是8的倍数
  • 所以,struct S4的总大小是1(c1)+ 7(填充)+ 16(s3)+ 8(d)= 32字节。

节省空间

        在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:

        让占用空间小的成员尽量集中在一起

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//例如: 
struct S1
{
	char c1;

	int i;

	char c2;
};
struct S2
{
	char c1;
	char c2;
	int i;
};

修改默认对齐数

#pragma 这个预处理指令,可以改变编译器的默认对齐数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#pragma pack(1)//设置默认对⻬数为1
struct S 
{
	char c1; 
	int i; 
	char c2; 
};
#pragma pack()//取消设置的对⻬数,还原为默认
int main()

{
	//输出的结果是什么?
	printf("%d\n", sizeof(struct S));
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 结构体的对齐规则:
  • 节省空间
  • 修改默认对齐数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档