热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c++基础知识(六)结构体字节对齐

我们在使用结构体的时候,有没有发现这样的情况,用sizeof(结构体)算出来的内存字节数与结构体里面的数据所占内存字节数总和不匹配。比如以下:

我们在使用结构体的时候,有没有发现这样的情况,用sizeof(结构体)算出来的内存字节数与结构体里面的数据所占内存字节数总和不匹配。

比如以下:

struct A
{
char a='0';//占用1个字节
int b=0;//占用4个字节
short c=0;//占用2个字节
};
本来总共应该是7个字节
但是用sizeof(结构体)算出来却是12个字节

今天我们来看看到底是怎么回事呢?原来啊,是编译器帮我们做了字节对齐。做字节对齐的目的是提高内存的访问效率。

比如32位CPU,每个总线周期都是偶数的地址开始访问读取32位的数据,但是如果数据不是按从偶数开始放置的,则读取则需要两个总线周期才能读到想要的数据。因此需要在内存存放数据时做内存对齐。

内存对齐需要遵守两个基本原则:

1、对于结构体的成员,第一个数据偏移地址为0,后面的数据的偏移量需要是其所占内存大小的整数倍。否则的话就需要进行填充字节数。

    举栗子:

    比如结构体A,很明显第一个成员为a,所以它的偏移地址为0,按照该原则,b占用是4个字节,所以b相对于a的偏移地址必须是4个整数倍,则最小为4,因为a占用1个字节,所以需要在a,b之间填充3个字节来进行字节内存对齐。同理,b的便宜地址变为了4,b本身占4个字节。b的地址为4----8,c的偏移地址就为8,本身占2个字节,偏移量是所占大小的4倍,不需要填充。

2、结构体所有数据内存对齐后,但是结构体也需要内存对齐,其整个结构体内存大小必须是结构体内中数据所占内存最大的整数倍。

   同样看结构体A,从1中我们知道a,b之间填充了3个字节,bc没有填充,总共占据了1+3+4+2=10个字节。根据原则2,结构体大小必须为4(因为该结构体数据中最大占4个字节)倍数,所以末尾再填充两个字节,总共是12个字节。

3、如果程序中有#pragma pack(n) 预编译指令,则所有成员对齐以n字节为准(即偏移量为N的整数倍),不在考虑当前类型以及最大结构体类型。



推荐阅读
  • 本文介绍了如何使用Java编程语言实现凯撒密码的加密与解密功能。凯撒密码是一种替换式密码,通过将字母表中的每个字母向前或向后移动固定数量的位置来实现加密。 ... [详细]
  • 本文详细介绍了 Node.js 中 OS 模块的 arch 方法,包括其功能、语法、参数以及返回值,并提供了具体的使用示例。 ... [详细]
  • 本文探讨了在 PHP 的 Zend 框架下,使用 PHPUnit 进行单元测试时遇到的 Zend_Controller_Response_Exception 错误,并提供了解决方案。 ... [详细]
  • 本文详细介绍了在MyBatis框架中如何通过#和$两种方式来传递SQL查询参数。使用#方式可以提高执行效率,而使用$则有助于在复杂SQL语句中更好地查看日志。此外,文章还探讨了不同场景下的参数传递方法,包括实体对象、基本数据类型以及混合参数的使用。 ... [详细]
  • 本文详细介绍了如何使用Linux下的mysqlshow命令来查询MySQL数据库的相关信息,包括数据库、表以及字段的详情。通过本文的学习,读者可以掌握mysqlshow命令的基本语法及其常用选项。 ... [详细]
  • STM32代码编写STM32端不需要写关于连接MQTT服务器的代码,连接的工作交给ESP8266来做,STM32只需要通过串口接收和发送数据,间接的与服务器交互。串口三配置串口一已 ... [详细]
  • 本文探讨了如何使用Scrapy框架构建高效的数据采集系统,以及如何通过异步处理技术提升数据存储的效率。同时,文章还介绍了针对不同网站采用的不同采集策略。 ... [详细]
  • 本文探讨了Linux环境下线程私有数据(Thread-Specific Data, TSD)的概念及其重要性,介绍了如何通过TSD技术避免多线程间全局变量冲突的问题,并提供了具体的实现方法和示例代码。 ... [详细]
  • 本文提供了一个关于AC自动机(Aho-Corasick Algorithm)的详细解析与实现方法,特别针对P3796题目进行了深入探讨。文章不仅涵盖了AC自动机的基本概念,还重点讲解了如何通过构建失败指针(fail pointer)来提高字符串匹配效率。 ... [详细]
  • 本报告记录了嵌入式软件设计课程中的第二次实验,主要探讨了使用KEIL V5开发环境和ST固件库进行GPIO控制及按键响应编程的方法。通过实际操作,加深了对嵌入式系统硬件接口编程的理解。 ... [详细]
  • 本文探讨了在Python中多线程与多进程的性能差异,特别是在处理CPU密集型任务和I/O密集型任务时的表现。由于全局解释器锁(GIL)的存在,多线程在利用多核CPU方面表现不佳,而多进程则能有效利用多核资源。 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • 如何使用Maven将依赖插件一并打包进JAR文件
    本文详细介绍了在使用Maven构建项目时,如何将所需的依赖插件一同打包进最终的JAR文件中,以避免手动部署依赖库的麻烦。 ... [详细]
  • LeetCode 102 - 二叉树层次遍历详解
    本文详细解析了LeetCode第102题——二叉树的层次遍历问题,提供了C++语言的实现代码,并对算法的核心思想和具体步骤进行了深入讲解。 ... [详细]
  • 编程解析:CF989C 花朵之雾 (构造算法)
    本文深入探讨了CF989C '花朵之雾'问题的构造算法,提供了详细的解题思路和代码实现。 ... [详细]
author-avatar
沉睡森林
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有