结构体内存对齐详解

2023-10-26

目录

一、结构体的对齐规则:

二、修改默认对齐数

三、位段

四、枚举 

五、联合(共用体)


一、结构体的对齐规则:

1. 第一个成员在与结构体变量偏移量为0的地址处。

2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的值为8

3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

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

图解:

offsetof()是一个宏,可以得到一个结构体成员在这个类型创建的变量中的偏移量。

百度笔试题: 写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明

#define OFFSETOF(type,name) (size_t)&(((type *)0)->name) 

为什么存在内存对齐?

1. 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特 定类型的数据,否则抛出硬件异常。

2. 性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访 问。

总体来说: 结构体的内存对齐是拿空间来换取时间的做法。

那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到: 让占用空间小的成员尽量集中在一起。

二、修改默认对齐数

 #pragma pack用法

#pragma pack(4)//默认对齐数改为4
struct S
{
	char ci;
	int i;
	char c2;
};
#pragma pack()// 默认对齐数该回来

顺便一提#pragma once 在头文件中使用,防止头文件被多次引用。

三、位段

位段的声明和结构是类似的,有两个不同:

1.位段的成员必须是 int、unsigned int 或signed int 。

2.位段的成员名后边有一个冒号和一个数字。

比如:

struct A
{
 int _a:2;
 int _b:5;
 int _c:10;
 int _d:30;
};

位段的内存分配

1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型

2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。

3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

四、枚举 

枚举类型的定义

enum Day//星期
{
 Mon,
 Tues,
 Wed,
 Thur,
 Fri,
 Sat,
 Sun
};
enum Sex//性别
{
 MALE,
 FEMALE,
 SECRET
};
enum Color//颜色
{
 RED,
 GREEN,
 BLUE
};

以上定义的 enum Day , enum Sex , enum Color 都是枚举类型。 {}中的内容是枚举类型的可能取值,也叫 枚举常量 。 这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。 例如:

enum Color//颜色
{
 RED=1,
 GREEN=2,
 BLUE=4
};

五、联合(共用体)

联合类型的定义

联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。 比如:

//联合类型的声明
union Un
{
 char c;
 int i;
};
//联合变量的定义
union Un un;
//计算连个变量的大小
printf("%d\n", sizeof(un));

联合大小的计算

1.联合的大小至少是最大成员的大小。

2.当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。 比如:

union Un1
{
 char c[5];
 int i;
};
union Un2
{
 short c[7];
 int i;
};
//下面输出的结果是什么?
printf("%d\n", sizeof(union Un1));
printf("%d\n", sizeof(union Un2));

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

结构体内存对齐详解 的相关文章

随机推荐

  • 解决Python OpenCV 读取IP摄像头(RTSP等)出现error while decoding的问题

    先来看一个简单的读取RTSP的示例程序 import cv2 cap cv2 VideoCapture rtsp admin admin 123 172 0 0 0 ret frame cap read while ret ret fram
  • 测试两个容器是否连通

    进入容器查看ip root f2b5cdfdc5ed private geth ip addr 1 lo
  • 如何打开Fedora 15命令行窗口CLI

    如何打开Fedora 15命令行窗口CLI 在DesktopFolder以外的桌面区域 右击可以看到Konsole 点击该快捷键 即可启动命令行窗口CLI 第一步 右击桌面 第二步 点击Konsole
  • python day03

    一 使用字符串 str helllo len str 用len函数求字符串长度 str upper 把字符串中的小写变成大写 str find 查找子串所在位置 str index 与find类似但找不到子串时会报错 str 2 从字符串中
  • c++ string函数详细返回值及用法!

    通过在网站上的资料搜集 得到了很多关于string类用法的文档 通过对这些资料的整理和加入一些自己的代码 就得出了一份比较完整的关于string类函数有哪些和怎样用的文档了 下面先罗列出string类的函数有哪一些 然后再罗列出函数的原型
  • 学习 Python 之 Pygame 开发魂斗罗(一)

    学习 Python 之 Pygame 开发魂斗罗 一 Pygame 回忆Pygame 1 使用pygame创建窗口 2 设置窗口背景颜色 3 获取窗口中的事件 4 在窗口中展示图片 1 pygame中的直角坐标系 2 展示图片 3 给部分区
  • 在中国,把区块链玩得转的公司有这几家

    时下最火的Fintech 金融科技 非区块链莫属 区块链正在成为国家层面规划的重点领域之一 区块链可以简单理解为一个由所有参与者公共维护的账本 账本信息的公开使得所有参与者可以一起来校验记账的正确性 使得区块链成为所有参与者可以信任的载体
  • ubuntu编译和安装opencv-3.4.13

    1 安装相关软件包 打开ubuntu 安装以下工具 sudo apt install build essential sudo apt install cmake git libgtk2 0 dev pkg config libavcode
  • 芯片验证从零开始系列(一)——芯片验证概论

    芯片验证从零开始系列 一 芯片验证概论 芯片开发流程 动态验证技术 静态验证技术 Emulation和FPGA原型开发 测试平台框架 检查设计 回归测试 声明 未经作者允许 禁止转载 推荐一个IC FPGA新手入门的好网站 快 点 击 进
  • STL源码剖析-Allocator

    一 第一级配置器 顾名思义 Allocator是用来做内存分配的 第一级配置器指的是当需要128bytes以上的内存时直接使用malloc和realloc进行内存分配 代码如下 第一级配置器 2023 04 07 template
  • 解决M1处理器款mac安装PR闪退问题 Premier 2020 Mac(已适配M1芯片,支持最新款M1芯片Mac)可稳定运行

    苹果公司最新发布的基于M1芯片的Mac笔记本电脑应该很多小伙伴都入手了 但是最新的Mac由于采用的是基于ARM架构的核心 对很多基于Intel 英特尔 处理器的老款mac的软件应用兼容不太好 导致很多现有软件安装好后无法运行 或者报错和闪退
  • elasticsearch query related

    public abstract class EsBaseDaoImpl
  • 汽车电子_EMC测试_RE试验整改

    测试设备DUT状态 DUT带壳 未安装导电泡棉 辐射抗扰度试验 辐射抗扰度试验 270MHz频段出现画面卡死 试验暂停未继续 BCI试验 CBCI出现故障 RE试验 30 200M H方向 Frequency MHz MaxPeak dB
  • Maven高级:多环境配置与应用

    Maven高级 Maven高级 分模块开发 Maven高级 依赖管理 Maven高级 聚合和继承 Maven高级 根据需求完成生成 开发 测试环境 并在各个环境间切换运行 一 多环境配置与应用 这一节中 我们会讲两个内容 分别是多环境开发和
  • vue3 antd 表格点击和点击背景色

    页面
  • win7在64位系统下编译openssl

    以前在笔记本上配置过openssl 0 9 8g版本 今天在公司的台式机上配置死活没配置成功 机器的系统是win7 64位 编译openssl 1 0 1e出现各种莫名的错误 最后无意中编译了1 0 0 a版本编译成功了 如果出现ml找不到
  • Selenium-Server-Standalone搭建

    一 概述 先说说背景吧 Selenium是一个优秀的自动化测试框架 可以模拟浏览器的各种操作来代替人工操作 不同的浏览器有 不同的driver来驱动 之前项目中使用的firefoxDriver chromeDriver有一个缺点 就是浏览器
  • VSCode配置MSVC+VSCode使用easyx库,2021.5.13日配置~~

    VSCode配置MSVC VSCode使用easyx库 2021 5 13日配置 想必很多人和我一样 想用vscode编程c easyx库不支持MinGW 一般人都是直接使用vs2019安装easyx库用来GUI编程 那么爱折腾的VSCod
  • 使用PHP简单操作Memcached

    记得一定要先启动Memcached哦 root localhost usr bin memcached d l 127 0 0 1 p 11211 m 150 u root 使用ps命令查看一下运行状态 root localhost ps
  • 结构体内存对齐详解

    目录 一 结构体的对齐规则 二 修改默认对齐数 三 位段 四 枚举 五 联合 共用体 一 结构体的对齐规则 1 第一个成员在与结构体变量偏移量为0的地址处 2 其他成员变量要对齐到某个数字 对齐数 的整数倍的地址处 对齐数 编译器默认的一个