C语言中的结构体的内存对齐,也叫做字节对齐 问题 分析

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

一。C语言结构体中的内存对齐如何计算

规则一:第一个成员在结构体变量偏移量为0的地址处

规则二: 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处

           对齐数 =编译器默认对齐数 与 该成员大小  比较后 取较小值

           默认对齐数:Linux中4字节,VS中8字节;

规则三 :结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍

规则四:如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

typedef struct Student {
    char sex;  占用1个字节                第1字节
    char sex1;  按照规则2,该成员占用1个字节 < vs中的8个字节,因此对齐数为1,,对齐到1的整倍数的字节处,即第二个字节。   第 2字节
    char sex2;  // 按照规则2,该成员占用1个字节 < vs中的8个字节,因此对齐数为1,,对齐到1的整倍数的字节处,即第三个字节。   第 3字节

//第4个字节没有用,空闲
    int age ;  // 按照规则2,该成员占用4个字节 < vs中的8个字节,因此对齐数为4,,对齐到4的整倍数 第五个字节。                           第5-8字节
    char name[6] ;//该成员是字符数组,要一个一个的看,数组中的每一个成员都是char,占用1个字节,小于 vs中的8个字节,对齐数为1,占用 9 - 14个字节

//第15,16 字节没有用,空闲
    int age2;        //        // 按照规则2,该成员占用4个字节 < vs中的8个字节,因此对齐数为4,,对齐到4的整倍数     ,1-14已经用了,就只能对齐到17了。占用17-20字节
    char name2[3];//3         //该成员是字符数组,要一个一个的看,数组中的每一个成员都是char,占用1个字节,小于 vs中的8个字节,对齐数为1,占用 21 - 23个字节

//第24 字节没有用,空闲
    char * address;//8        占用8,=  vs中的8个字节,因此对齐数为8,25-32个字节。
    //总和为:4+4+8+4+4+8 = 32字节
}_Student;

typedef struct Student {
	char sex;//占用1个字节                第1字节
	char sex1;//按照规则2,该成员占用1个字节 < vs中的8个字节,因此对齐数为1,,对齐到1的整倍数的字节处,即第二个字节。   第 2字节
	char sex2;// 按照规则2,该成员占用1个字节 < vs中的8个字节,因此对齐数为1,,对齐到1的整倍数的字节处,即第三个字节。   第 3字节

	//第4个字节没有用,空闲
	int age;//按照规则2,该成员占用4个字节 < vs中的8个字节,因此对齐数为4,,对齐到4的整倍数 第五个字节。                           第5-8字节
	char name[6];//该成员是字符数组,要一个一个的看,数组中的每一个成员都是char,占用1个字节,小于 vs中的8个字节,对齐数为1,占用 9 - 14个字节

//第15,16 字节没有用,空闲
	int age2; // 按照规则2,该成员占用4个字节 < vs中的8个字节,因此对齐数为4,,对齐到4的整倍数     ,1-14已经用了,就只能对齐到17了。占用17-20字节
	char name2[3];//该成员是字符数组,要一个一个的看,数组中的每一个成员都是char,占用1个字节,小于 vs中的8个字节,对齐数为1,占用 21 - 23个字节

//第24 字节没有用,空闲
	char * address;//8        占用8,=  vs中的8个字节,因此对齐数为8,25-32个字节。
	//总和为:4+4+8+4+4+8 = 32字节
}_Student;



void main() {
	_Student s;
	int result = sizeof(_Student);
	printf("result = %d\n", result);// 32

	//offsetof 宏可以使用 offsetof 宏计算一个结构体成员的偏移量。

	printf("%zd\n", offsetof(_Student, sex));  // 0
	printf("%zd\n", offsetof(_Student, sex1));  // 1
	printf("%zd\n", offsetof(_Student, sex2));  //2
	printf("%zd\n", offsetof(_Student, age));  // 4
	printf("%zd\n", offsetof(_Student, name));  // 8
	printf("%zd\n", offsetof(_Student, age2));  // 16
	printf("%zd\n", offsetof(_Student, name2));  // 20
	printf("%zd\n", offsetof(_Student, address));  // 24

	printf("断点在这里");
}

二,带来的问题以及如何fix

从上面看到:在windows vs上,内存对齐的标准是8.

在linux 上,内存对齐的标准是4.

这会有一个问题,当我们在windows使用文件写的方式,写入了一个二进制文件(假设叫做config.bin)。需要在linux 上读取,这就有问题了。写入的时候struct占用了80个字节,但是读取的时候就不一定这个struct就占用80个字节了。

解决方案:如有这样的需求(在windows上生成的文件,需要在linux 上读取)

建议我们在给这个struct前面加上

#param pack(1) //这表示当前使用1字节对齐的方式,既然使用了1字节对齐,就不存在8字节,4字节的问题了


typedef struct student{
char sex;
int age;
char name[64];

}

#param pack() //结束标记,表示只是如上的代码 使用1 字节对齐

C语言字节对齐详解 字节对齐详解 阅读详情

相关推荐

C语言字节对齐

本文为博主个人学习总结记录,如有不正,欢迎指正。

qq_45583706的博客 1654

C语言----字节对齐

C语言字节对齐

ftzchina的博客 5565

C语言基础 - 结构体类型字节对齐总结

一、什么是字节对齐 在计算机中,内存空间是按照字节(1B = 8 bit)划分的,每一个字节都有一个编号,这就是字节的地址。理论上可以从任意起始地址访问任意数据类型的变量,但在实际使用中,访问特定数据类型变量时需要在特定的内存起始地址进行访问,这就需要各种数据类型按照一定的规则在空间上进行排列,而不是顺序地一个接一个地存放,这就是字节对齐。 如果一个变量的内存起始地址正好是其数据类型长度的整数倍,就被称作自然对齐。比如,在32系统下,假设一个int型变量的起始地址为0x00000004,那它就是自然对齐

yunfan 6980

c语言字节对齐

c语言驱动变成,网络通讯内核模块编程

zouweisj的博客 3783

字节对齐讲解

讲述什么是字节对齐字节对齐的作用以及原因等等,通过各案例帮你快速了解字节对齐

Demondai999的博客 1万+

【C语言编程实战案例】第10课--C语言对齐问题,含结构体、栈内存以及位域对齐

根据结构体圆整的要求,0x0000~0x0009=10字节,(10+2)%4=0。例如C/C++编译器提供的#pragma pack(n) n=1,2,4等,让编译器在生成目标文件时,使内存数据按照指定的方式排布在1,2,4等字节整除的内存地址处。(2)为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员大小的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。

xzs51job的专栏 1217

C语言结构体字节对齐问题

C/C++结构体字节对齐问题1 前言2 举例3.其他 1 前言 对于结构体字节对齐问题,我发现我一直有一个误区,正是这个误区,给我带来了很大困扰,今天突然顿悟,在此记录一下,希望能帮到大家。 2 举例 #include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)0)->f)) struct AD { int a; char b[13]; double c;}; #pragma pack(push) #prag

stone322的博客 762

结构体字节对齐

字节对齐是计算机系统中用于提高内存访问效率的一个重要概念。不同的数据类型(如整数、浮点数、结构体等)在内存中的存储位置往往需要按照特定的规则进行对齐,以便提高程序的运行速度并保证系统的稳定性。

qq_51097294的博客 2416

C语言的struct/union字节对齐详解

        C 语言的一大优势就是对内存空间的控制,当然,在面向对象语言的压力下,程序员更喜欢轻松的语言,不喜欢自己还要顾虑内存空间。        可是,C 语言仍然有很强的生命力,尤其是在操作系统、嵌入式系统这两方面,因为要直接操作硬件,C语言就显现出自己强大的体制、机制、逻辑优势。        C语言内存控制,有一个始终困扰初学者的问题字节对齐!看一段程序: struct stExample { char a; char b short c;

草莽农夫 1万+

C语言字节对齐

C语言字节对齐参考来源字节对齐概念字节对齐的作用分类结构体对齐简单示例对齐准则 参考来源 文章主要参考自以下文章,进行整合补充: C语言内存对齐详解 C语言字节对齐问题详解 什么是字节对齐,为什么需要字节对齐 字节对齐概念   在C语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组、结构、联合等)的数据单元。在结构中,编译器为结构的每个成员按其自然边界(alignment)分配空间。各个成员按照它们被声明的顺序在内存中顺

菜鸟不会飞 2303

C语言字节对齐解析

这两天去面试被连续两次问到的字节对齐问题

wocacaaa的专栏 865

编译过程中的字节对齐

c语言 编译 字节对齐

u010546263的博客 944

c 取short 的高低位_C/C++编程笔记:C语言对齐问题,含结构体、栈内存以及位域对齐...

引言考虑下面的结构体定义:假设这个结构体的成员在内存中是紧凑排列的,且c1的起始地址是0,则s的地址就是1,c2的地址是3,i的地址是4。现在,我们编写一个简单的程序:运行后输出:为什么会这样?这就是字节对齐导致的问题。本文在参考诸多资料的基础上,详细介绍常见的字节对齐问题。因成文较早,资料来源大多已不可考,敬请谅解。一,什么是字节对齐现代计算机中,内存空间按照字节划分,理论上可以从任何起始地址访...

weixin_33661631的博客 501

C语言字节对齐问题详解

转自:添加链接描述 引言 考虑下面的结构体定义: 1 typedef struct{ 2 char c1; 3 short s; 4 char c2; 5 int i; 6 }T_FOO; 假设这个结构体的成员在内存中是紧凑排列的,且c1的起始地址是0,则s的地址就是1,c2的地址是3,i的地址是4。 现在,我们编写一个简单的程序: 复制代码 1 int main(void){ 2 T_FOO a; 3 printf(“c1 -> %d, s

m0_48633959的博客 775

JNA内存对齐导致的结构体数组传输错误

因为Java中结构体内存对齐方式默认是按照4字节字节对齐,也就是4字节的整数倍,但是C中默认是1字节对齐,因此需要将Java结构体STRUCT_A的内存方式设置成和C相同:1字节对齐结构体数组STRUCT_A[] sttpConfigTable从Java传递到C后,第一个元素取值正常,第二个元素取值异常,例如在C中取sttpConfigTable[1]的name属性乱码,不是“名称2”。

zcbdandan的博客 217

关于C语言中的结构体对齐问题

关于C语言中的结构体对齐问题 作者: infobillows 发表日期: 2007-09-12 20:05 点击数: 2273 1,比如: struct{ short a1; short a2; short a3; }A; struct{ lon

可达鸭技术博客 385

queue队列怎么存结构体_C语言结构体到底占多少内存?简单!一文助你解决结构体内存问题...

前言本文主要介绍的是C/C++中 结构体的所占用内存问题做以分析,希望对于广大读者有一些帮助。在编写C语言一下程序的时候:struct data{int iNum;float fNum;long lNum;};结构体里会包括int char double,它们要占用的空间不同,系统为一个结构体开辟内存空间时,会有2种选择。第一种:节省空间的方案,以上面的例子来说的话,就是4(int) + 1(ch...

weixin_39581972的博客 976

链表—C语言结构体

C语言语法练习

2303_81279773的博客 2407
上一篇: C语言中函数类型,函数指针类型,函数指针变量
下一篇: C语言中的共用体 和 枚举
hunandede
博客等级 码龄19年 2450粉丝 403原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值