结构对齐填充、填充的最大尺寸以及结构成员的顺序

2023-12-07

自从我发现我的 sizeof() 运算符没有返回我期望的结果以来,我一直在学习结构数据填充。根据我观察到的模式,它将结构成员与最大的数据类型对齐。那么例如...

struct MyStruct1
{
    char a;     // 1 byte
    char b;     // 1 byte
    char c;     // 1 byte
    char d;     // 1 byte
    char e;     // 1 byte
                // Total 5 Bytes

    //Total size of struct = 5 (no padding)
};

struct MyStruct2
{
    char a;     // 1 byte
    char b;     // 1 byte
    char c;     // 1 byte
    char d;     // 1 byte
    char e;     // 1 byte
    short f;    // 2 bytes
                // Total 7 Bytes
    
    //Total size of struct = 8 (1 byte of padding between char e and short f
};

struct MyStruct3
{
    char a;         // 1 byte
    char b;         // 1 byte
    char c;         // 1 byte
    char d;         // 1 byte
    char e;         // 1 byte
    int f;          // 4 bytes
                    // Total 9 bytes

    //Total size of struct = 12 (3 bytes of padding between char e and int f
};

但是,如果将最后一个成员设置为 8 字节数据类型,例如 long long,它仍然只添加 3 字节填充,形成四字节对齐结构。但是,如果我以 64 位模式构建,它实际上会对齐 8 个字节(最大的数据类型)。我的第一个问题是,我说它将成员与最大的数据类型对齐是错误的吗?此声明对于 64 位构建来说似乎是正确的,但在 32 位构建中仅适用于最多 4 字节数据类型。这与 CPU 的本机“字”大小有关吗?还是程序本身?

我的第二个问题是,以下内容是否完全浪费空间和糟糕的编程?

struct MyBadStruct
{
    char a;             // 1 byte
    unsigned int b;     // 4 bytes
    UINT8 c;            // 1 byte
    long d;             // 4 bytes
    UCHAR e;            // 1 byte
    char* f;            // 4 bytes 
    char g;             // 1 byte
                        // Total of 16 bytes

    //Total size of struct = 28 bytes (12 bytes of padding, wasted)
};

如何填充不是标准的一部分。因此可以在不同的系统和编译器上以不同的方式完成。通常这样做是为了使变量按其大小对齐,即 size=1 -> 无对齐、size=2 -> 2 字节对齐、size=4 -> 4 字节对齐等等。对于 size=8,通常是 4 或 8 字节对齐。结构本身通常是 4 或 8 字节对齐的。但是 - 只是重复一下 - 它取决于系统/编译器。

在你的情况下,它似乎遵循上面的模式。

So

char a;
int  b;

将为 4 字节对齐 int 提供 3 字节填充。

and

char a1;
int  b1;
char a2;
int  b2;
char a3;
int  b3;
char a4;
int  b4;

最终将成为 32 字节(再次以 4 字节对齐 int)。

But

int  b1;
int  b2;
int  b3;
int  b4;
char a1;
char a2;
char a3;
char a4;

由于 int 已经对齐,因此将仅为 20。

因此,如果内存很重要,请将最大的成员放在第一位。

但是,如果内存并不重要(例如,因为结构体使用得不多),那么最好将事物保持逻辑顺序,以便代码易于人类阅读。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

结构对齐填充、填充的最大尺寸以及结构成员的顺序 的相关文章

  • MVC 重定向到没有控制器的视图

    希望应该是一个简单的 我创建了一个通用错误视图 当整个站点的操作方法内发生异常时 我想显示该视图 我创建了一个部分页面 所有导航都位于其中 因此我不需要在此视图上使用控制器 那么如何从控制器内的操作方法重定向到它 像这样的东西 HttpPo
  • 扫描文本文件时如何跳过行?

    我想扫描一个文件并在阅读之前跳过一行文本 我试过 fscanf pointer n struct test i j 但这个语法只是从第一行开始 我可以使用 scanf 使用以下指令跳过行 fscanf config file n n 格式字
  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • 如何将字节块读入结构体

    我有一个需要处理的资源文件 它包含一组文件 首先 资源文件列出了其中包含的所有文件 以及一些其他数据 例如在此结构中 struct FileEntry byte Value1 char Filename 12 byte Value2 byt
  • F10键没被抓住

    I have a Windows Form and there overriden ProcessCmdKey However this works with all of the F Keys except for F10 I am tr
  • 将成员函数作为参数传递/c++

    我想用 C 实现一个类b可以通过封装该迭代器类型的成员集进行某种迭代 喜欢 b object for each x do function f so 函数 f会得到每个人的x成员并做任何事情 比方说 void function f x me
  • 使用 openssl 检查服务器安全协议

    我有一个框架应用程序 它根据使用方式连接到不同的服务器 对于 https 连接 使用 openssl 我的问题是 我需要知道我连接的服务器是否使用 SSL 还是 TLS 以便我可以创建正确的 SSL 上下文 目前 如果我使用错误的上下文尝试
  • 导出到 CSV 时 Gridview 出现空行

    这个问题是由进一步讨论引发的这个问题 https stackoverflow com questions 6674555 export gridview data into csv file 6674589 noredirect 1 com
  • 如何使用泛型类型的 DataContractSerializer 编写自定义序列化器?

    我想编写一个自定义序列化器 用于将会话状态存储到Azure 缓存 预览版 这意味着这个自定义序列化器必须实现IDataCacheObjectSerializer 如果我错了 请告诉我 我需要编写这个自定义序列化程序的原因是我需要序列化一些包
  • 在“using”语句中使用各种类型 (C#)

    自从C usingstatements只是try finally dispose 的语法糖 为什么它接受多个对象仅当它们属于同一类型时 我不明白 因为它们需要的只是 IDisposable 如果它们都实现 IDisposable 应该没问题
  • 为什么重载方法在 ref 仅符合 CLS 方面有所不同

    公共语言规范对方法重载非常严格 仅允许根据其参数的数量和类型来重载方法 如果是泛型方法 则根据其泛型参数的数量进行重载 根据 csc 为什么此代码符合 CLS 无 CS3006 警告 using System assembly CLSCom
  • 如何在 C# 中使用 XmlDsigC14NTransform 类

    我正在尝试使用规范化 xml 节点System Security Cryptography Xml XMLDsigC14nTransformC net Framework 2 0 的类 该实例需要三种不同的输入类型 NodeList Str
  • 更改其他页面的主窗口内容

    在 WPF 应用程序的主窗口中 我有一个 Badged 元素 来自材料设计 这是我的代码
  • 从包含大量文件的目录中检索文件

    我的目录包含近 14 000 000 个 wav 格式的音频样本 所有普通存储 没有子目录 我想循环浏览文件 但是当我使用DirectoryInfo GetFiles 在该文件夹上 整个应用程序冻结了几分钟 可以用另一种方式完成吗 也许读取
  • 为什么WCF中不允许方法重载?

    假设这是一个ServiceContract ServiceContract public interface MyService OperationContract int Sum int x int y OperationContract
  • 为什么C语言中可以使用多个分号?

    在 C 中我可以执行以下操作 int main printf HELLO WORLD 它有效 这是为什么 我个人的想法 分号是一个 NO OPERATION 来自维基百科 指示符 拥有一大串分号与拥有一个分号并告诉 C 语句已结束具有相同的
  • 如何将 CSV 文件读入 .NET 数据表

    如何将 CSV 文件加载到System Data DataTable 根据CSV文件创建数据表 常规 ADO net 功能是否允许这样做 我一直在使用OleDb提供者 但是 如果您正在读取具有数值的行 但希望将它们视为文本 则会出现问题 但
  • 将一个 long 转换为两个 int 以进行重构

    我需要将一个参数作为两个 int 参数传递给 Telerik Report 因为它不能接受长参数 将 long 拆分为两个 int 并在不丢失数据的情况下重建它的最简单方法是什么 使用掩蔽和移位是最好的选择 根据文档 long 保证为 64
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D

随机推荐

  • 32 位模式下的 NASM x86_64 汇编:为什么该指令会生成 RIP 相对寻址代码?

    bits 32 global start section data str hello db HelloWorld 0xa str hello length db str hello section text start mov ebx 1
  • 不使用中间文件将内存中的数据传输到FTP服务器

    我有一些用 PHP 编码的 JSON 数据json encode 它看起来像这样 site site1 nbrSicEnt 85 我想要做的是将数据作为文件直接写入 FTP 服务器上 出于安全原因 我不希望在将文件发送到 FTP 服务器之前
  • Rubymine 6.0.2,无法调试

    在我新安装的 OSX Mavericks 上 我想尝试一下 Rubymine 但无法让调试器工作 尽管我设法使用 IntelliJ 和 ruby 插件在 Windows 7 上让它工作 这是我所做的 XCode 和命令行工具已安装 home
  • jberet 上的独立示例 (jsr352)

    是否有使用 jberet 作为独立模块来执行批处理作业 一直在获取与 WildFly 一起使用的样本 惊讶地发现它在尝试一些示例时寻找容器来加载实现 任何关于为什么 为什么不的见解都会有帮助 以下是如何在独立应用程序中使用 jberet 的
  • 根据模式连接线

    我有以下文件 test 1 My 2 Hi 3 我需要一种使用 cat grep 或 awk 给出以下输出的方法 test1 My2 Hi3 我如何通过单个命令实现此目的 就像是 cat file txt grep awk 请注意 在原始文
  • Python - 从 SharePoint 网站下载文件

    我需要将文件下载并上传到 Sharepoint 站点 这必须使用 python 来完成 我的网站将是https ourOrganizationName sharepoint com Followed通过进一步的链接 最初我以为我可以使用 R
  • 从 Spring+Mongo 中的文档数组中删除项目

    我在 mongodb 中有一个这样的文档集合 id ObjectId 592bc37c339e7a23788b4c7c trips tripGcsId 5937f86e339e7a2a58ac3186 tripCounter NumberL
  • 当模块存在时,为什么 VS Code 会抛出“找不到模块 'typescript'.ts(2307)”?

    我在用着import as ts from typescript 在 ts 文件中导入打字稿 该文件运行良好 但 VS Code 告诉我Cannot find module typescript ts 2307 有什么办法可以抑制这个问题吗
  • JavaScript 中奇怪的意外标记非法 [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 我有一个无法解决的语法错误 根据 W3 jQuery
  • 检查 SQL Server 实例是否在本地计算机上?

    我想确定我连接的 SQL Server 是否在本地计算机上 我知道连接到 SQL Server 时有很多方法可以识别 SQL Server 的服务器 实例名称 但是指定服务器名称的方法有很多不同 我不想自己在 IP 地址之间进行比较 机器名
  • JS/jQuery 在滚动事件上交换图像

    我有一个网站菜单 其工作原理与此类似 http jsfiddle net sinky XYGRW 在 stackoverflow 上发现 我的问题是 设计师希望将导航 主页按钮 中的徽标切换为较小的图标 不仅仅是缩小尺寸 而且实际上改变了图
  • 为什么像 chrome://downloads 或 chrome://apps 这样的本地 chrome-url 在无头模式下不起作用?

    我正在尝试访问 chrome 本地网址 但这不起作用 headless chrome 支持本地 URL 吗 我今天正在寻找这个 发现这个 大多数 chrome 内部页面不是在无头模式下实现的 这是 headless Chrome 本身的限制
  • 避免空引用异常

    显然 代码中的绝大多数错误都是空引用异常 是否有任何通用技术可以避免遇到空引用错误 除非我弄错了 否则我知道在 F 等语言中不可能有空值 但这不是问题 我问的是如何避免 C 等语言中的空引用错误 当向用户显示空引用异常时 这表明由于开发人员
  • 使用javascript动态启用和禁用css文件?

    我对 JavaScript 很陌生 我正在创建一个多语言网站 它包含 rtl 和 ltr 语言 我有两个用于语言的 css 当用户更改语言时 我想加载相应的 css 文件 这样可以吗 如果没有建议任何替代方法 可以使用 javascript
  • NSFetchedResultsController swift 部分

    我有一个表视图 它从具有 3 个字段的 CoreData 实体获取数据 firstName String lastName String 和 did NSNumber 这是一个可以打开或关闭的 UISwitch 我想用名字和姓氏填充表 但第
  • pydantic.error_wrappers.ValidationError:FastAPI

    我正在 fastapi 中进行增删改查 我有一个用户模型 并且创建了另一个名为 showuser 的模型 以仅显示查询中的某些特定字段 但是当我执行请求时 出现错误 我只是希望我的请求显示我在 showuser 中拥有的字段 我的模式 fr
  • Rplot.gam错误“1中的错误:object$nsdf:长度为0的参数”

    我正在尝试在 R 中绘制一个 gam 对象 这是我用 gam 包制作的 我收到了报告中相同的错误1 object nsdf 中的错误 使用plot gam 时长度为0 的参数 然而 在那里找到的解决方案 更新到最新版本 我认为 对我来说不起
  • 如何强制禁用 intel_pstate?即使在 grub 中使用 intel_pstate=disable 选项,intel_pstate 也会在重新启动时启用

    我正在尝试使用 cpu 频率缩放来设置 cpu 频率 在我的系统中 仅支持 powersave 性能频率缩放调节器 在其他文档中解释过 默认情况下 intel pstate 是启用的 并且它只支持 powersave 性能频率缩放 gove
  • 破坏红色区域的内联汇编

    我正在编写一个加密程序 其核心 一个广泛的乘法例程 是用 x86 64 汇编语言编写的 既是为了速度 也是因为它广泛使用诸如adc我不想内联这个函数 因为它很大并且在内循环中被调用多次 理想情况下 我还想为此函数定义一个自定义调用约定 因为
  • 结构对齐填充、填充的最大尺寸以及结构成员的顺序

    自从我发现我的 sizeof 运算符没有返回我期望的结果以来 我一直在学习结构数据填充 根据我观察到的模式 它将结构成员与最大的数据类型对齐 那么例如 struct MyStruct1 char a 1 byte char b 1 byte