C语言结构体存储空间分配的原则

我们在嵌入式编程中经常用到结构体,结构体内成员变量的声明顺序不同,会带来结构体整体存储空间大小的不同,这是因为在C语言里,结构体里元素存储要对齐,这个“对齐”里面包含了很多微妙的东西。

结构体内存存储空间分配的原则
编译器按照成员列表顺序一个接一个地给每个成员分配内存。只有当存储成员时需要满足正确的边界对齐要求时,成员之间才可能出现用于填充的额外内存空间。

而且还有3点原则

  1. 结构体变量的首地址要能够被其最宽基本类型元素的大小所整除。
  2. 结构体的每个元素相对于结构体首地址的偏移量(offset)都是元素大小的整数倍,如有需要编译器会在元素之间加上填充字节(internal adding)。
  3. 结构体的总大小为结构体最宽基本类型元素大小的整数倍,如有需要编译器会在最末一个元素之后加上填充字节(trailing padding)。

下面来看几个例子(以32位arm或单片机系统为例):
sizeof操作符能够得出一个结构的整体长度,包括因边界对齐而跳过的那些字节。所以一般都用sizeof来计算其所占存储空间,比如sizeof(t1)、sizeof(int)、sizeof(char)就可以计算结构体t1、int型、char型变量的存储空间大小。

struct t1
{int a;char b;char c;
};

首先创建的是int类型的a为4字节,但是其后一个b只占1个字节,所以不要和char b对齐。因为其后一个c只占1个字节,所以也不用对齐。所以结构体t1一共占:4+1+1=6个字节,但是根据要求3,结构体的总大小为结构体最宽基本类型元素大小的整数倍。而在这个例子中,最宽的元素为int a,为4字节。所以最后结构体t1的总大小必须为4的倍数,因此最终的字节数为8。所以,这里编译器自动充填了2字节的充填字节。

下面让我们将例1中元素的顺序调一下位置看看:

struct t2
{char b;int a;char c;
};

计算后可以得到t2总字节数为12。是不是很疑惑,为什么就是位置换了一下结果会有所不同呢?这就是前面定义中所说的顺序的问题。来分析一下,首先创建的是 char b为1字节,然后是 int a为4字节,要对齐,所以应该在b后添加3个字节创建 int a,因为最后的cahr c只占1字节,所以不用充填,所以总字节数为:4+4+1=9,还是因为要求3,应该为4的倍数,所以总字节为12(3个充填字节)。

那么加上数组呢?

struct t3
{int a;char b[9];char c;
};

a占4个字节,b和c分别占9个字节和1个字节,加起来10个字节,但是因为要求3,这里最宽的元素为int,所以要为4的倍数,所以总共需要16个字节。

再掉一下位置

struct t4
{char b[9];int a;char c;
};

b占9字节,a占4字节,为了对齐,这时候应该是12(9+3,因为char 比int少3字节,所以为了对齐要加上那3字节)+4个字节,后面又来一个c 也是char,为了对齐加4(1+3),所以总共是20个字节。
而t3因为后面两个元素类型一致,所以可以先和在一起分配,然后对齐。
所以可以知道,要不要对齐是看基本元素类型的,比如虽然char b[9]比int a占的字节要多,但是因为基本元素类型不一样,所以还是要对齐。

C语言结构体存储空间分配的原则相关推荐

  1. C语言 结构体存储空间分配

    这两天在看结构体,一直在琢磨结构体的存储空间分配的问题,琢磨了半天总算明白了.和大家分享一下,希望能有所帮助. 相信大家都知道结构体里元素存储要对齐吧,话虽是没错,只是这个"对齐" ...

  2. c语言结构体变量所占字节计算,【C语言】结构体占用字节数及存储与空间分配...

    我们都知道在数据类型中,char类型占1个字节,short占2个字节,int占4个字节,long占8个字节等等. 在计算结构体大小时需要考虑其内存布局,结构体在内存中存放是按单元存放的,每个单元多大取 ...

  3. c++ new一个结构体_C语言结构体,又一个纸老虎,纯干货讲解(附代码)

    来源:网络,排版整理:晓宇 微信公众号:芯片之家(ID:chiphome-dy)结构体的定义结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构.结构体和其他类型基础数 ...

  4. C语言结构体对齐[转]

    C语言结构体对齐也是老生常谈的话题了.基本上是面试题的必考题.内容虽然很基础,但一不小心就会弄错.写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的 ...

  5. C语言结构体字节对齐规则

    C语言结构体字节对齐规则 基本规则 规则1 :结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的地方(比如int在 ...

  6. linux中c语言结构体详解,Linux C语言结构体-学习笔记

    Linux C语言结构体简介 前面学习了c语言的基本语法特性,本节进行更深入的学习. 预处理程序. 编译指令: 预处理, 宏定义, 建立自己的数据类型:结构体,联合体,动态数据结构 c语言表达式工具 ...

  7. python展开 c函数中的宏预处理_Linux C语言结构体-学习笔记

    Linux C语言结构体简介 前面学习了c语言的基本语法特性,本节进行更深入的学习. 预处理程序. 编译指令: 预处理, 宏定义, 建立自己的数据类型:结构体,联合体,动态数据结构 c语言表达式工具 ...

  8. 深度剖析C语言结构体

    深度剖析C语言结构体 1.什么是结构 2.结构体的声明 3.结构体变量的定义 4.结构成员变量的访问: 5.结构体变量的初始化: 6.嵌套的结构体: 7.结构体数组: 8.typedef 9.结构的自 ...

  9. C语言结构体和链表结合,C语言结构体与链表

    C语言结构体与链表 第 10章 CHAPTER 10 结构体与共用体 学习目标 本章主要介绍结构体的定义和使用方法,然后介绍链表的概念和相关操作,最后介绍两种新的数据类型--共用体和枚举.通过本章的学 ...

最新文章

  1. Nature Plants:河南大学王学路团队揭示大豆与根瘤菌匹配性的进化及其分子机制...
  2. Linux 命令之 mv -- 移动文件/重命名文件
  3. Linux系统fb驱动信息,Linux下利用fb驱动截屏
  4. 无缝的缓存读取:双存储缓存策略
  5. Hudson dryRun jobs break after upgrade from 2.2.0 to 2.2.1
  6. idea自动导包_IDEA已经世界第一了,听说你还不会?
  7. SparkSQL实践
  8. 基于Vue和Node.js的电商后台管理系统
  9. python深度学习基于pytorch——arange、linspace 函数生成数组
  10. python 输入一个整数,将该整数逆向输出
  11. 细数我曾经看过的动画片(不完全统计)
  12. 方舟同步服务器信息,方舟服务器备份和数据库备份
  13. 社区购物、社区买菜小程序源码
  14. “数据结构”课程的内容
  15. 第一章:客户端网页编程简介
  16. 51单片机PWM源码讲解 小车调速 呼吸灯等应用
  17. 远程linux云主机,Linux实验室 远程连接Linux云主机方法
  18. 具体应如何办理股票开户?
  19. esp8266-01s介绍与使用
  20. html怎么设置一个div可以左右移动,利用css 使div上下左右移动

热门文章

  1. 专题10:如何应对面试官的拷问—你了解python的装饰器吗?
  2. 哪类数字域名更优秀?数字域名价值高吗?
  3. 【C++ Primer Plus(6)】CH2 开始学习C++
  4. Spring自动装配及自动注入
  5. Naked dog come out
  6. 一个想法:成立草根技术联盟对开发人员进行技术定级解决企业员工招聘难问题!
  7. 第十三章 失业、通货膨胀和经济周期
  8. 计算机学院教学指导委员会职责,教学指导委员会
  9. Linux网络配置及”Job for network.service failed“错误解决
  10. [BZOJ 3730] 震波