当前位置: 首页 > news >正文

内存对齐与变量/结构体分析

C++ 中,内存对齐(Memory Alignment) 是编译器在为变量或结构体分配内存时,为了提高 CPU 访问效率 而进行的一种内存布局策略。
它的核心思想是:数据的起始地址要满足一定的对齐要求,而不是紧密地一个接一个地存放。


1️⃣ 为什么需要内存对齐

  1. 硬件原因
    许多 CPU 在访问某些数据类型时,要求数据的地址是特定倍数,否则访问效率会下降,甚至直接抛出硬件异常。
    例如:32 位 CPU 通常要求 4 字节的 int 变量地址是 4 的倍数。

  2. 性能原因
    CPU 以字(word)为单位读取内存(一次通常读取 2/4/8 字节)。
    如果数据没有按字对齐,CPU 可能需要两次总线访问才能取到完整数据,降低效率。


2️⃣ 对齐规则(常见情况)

编译器通常遵循以下规则(不同平台/编译器可能略有差异):

类型对齐值(alignment)
char1 字节
short2 字节
int / float4 字节
double8 字节(在 64 位系统上通常是 8)

👉 对齐值 = min(类型自身大小, 编译器默认对齐值)

  • 例如:在默认对齐值为 8 的 64 位系统上:

    • int 的大小 4,取 min(4, 8) → 对齐值 4 , 这意味着每个 int 的 起始地址必须是 4 的倍数。
    • double 的大小 8,取 min(8, 8) → 对齐值 8

3️⃣ 结构体的对齐

结构体(struct/class)对齐比单一变量更复杂,需要遵循 成员对齐 + 整体对齐

规则

  1. 每个成员 的地址必须是其自身对齐值的整数倍。
  2. 结构体总大小 必须是其 最大成员对齐值 的整数倍(必要时在末尾填充 padding)。

例子 1

struct A {char c;   // 1 字节int i;    // 4 字节
};

内存布局:

| c | pad(3) | i i i i |
  • char c 占 1 字节,接着要对齐到 4 字节边界 → 填充 3 字节。
  • 总大小 = 8 字节,而不是 5。

例子 2:调整顺序减少填充

struct B {int i;char c;
};

布局:

| i i i i | c | pad(3) |
  • 总大小还是 8(因为整体必须是最大成员对齐值 4 的倍数)。
  • 但如果有多个成员,合理排序可以减少浪费。

4️⃣ 控制对齐方式

编译器提供手段来改变默认对齐:

  1. #pragma pack(n)

    • 让结构体按 n 字节对齐。
    #pragma pack(1)
    struct C {char c;int i;
    };
    #pragma pack()
    

    结果大小 = 5 字节(几乎无 padding),但可能降低访问效率。

  2. alignas (C++11)

    • 指定特定变量或结构体的对齐要求。
    struct alignas(16) D {double d;
    };
    

    强制 D 的对齐为 16 字节。

  3. alignof (C++11)

    • 查询类型的对齐值。
    std::cout << alignof(double) << std::endl;
    

5️⃣ 小结

概念说明
内存对齐数据地址按特定字节边界存放
原因提高 CPU 访问速度,避免硬件异常
结构体大小成员最大对齐值的倍数
优化成员排序、#pragma packalignas

一句话记忆

对齐是以空间换时间:多花几个字节的填充 (padding),换来 CPU 读写的高效和安全。

http://www.dtcms.com/a/402962.html

相关文章:

  • 常见开发语言在 Windows 上的默认编码格式
  • 卫朋:AI硬件产品怎么做?——雷达模块选型实操
  • 从另一个视角看Transformer:注意力机制就是可微分的k-NN算法
  • [优选算法专题三.二分查找——NO.21山脉数组的峰顶索引]
  • 湖南营销型网站建设推广如何更改网站标题
  • 云原生网络基础设施的核心组件Envoy
  • KubeSphere 社区版即将发布:开启云原生新篇章
  • K8s学习笔记(五) Velero结合minnio业务数据备份与恢复
  • 23种设计模式——组合模式(Composite Pattern)
  • 培训机构网站开发汉中杨海明
  • 2- 十大排序算法(希尔排序、计数排序、桶排序)
  • 哈尔滨服务器托管优选-青蛙云
  • 【MySQL】JDBC
  • sogoupinyin输入法,LINUX版输入中文不显示中文
  • 自动化运维工具 Ansible:集中化管理服务器完全指南
  • 电影网站的建设目标做网站的公司简称什么行业
  • 【ThreeJs】【HTML载入】Three.js 中的 CSS2DRenderer 与 CSS3DRenderer 全面解析
  • (50)elasticsearch服务部署-有状态负载(华为云平台CCE)
  • 【时序预测-5】FFT、STL、ARIMA频域特征和时序分解
  • Kotlinx Serialization 指南
  • SpringBoot @Scheduled 注解详解
  • layui 表格行级 upload 上传操作
  • 【Unity 入门教程】三、如何设置自定义字体(解决中文乱码问题)
  • STM32开发(FreeRTOS实时操作系统)
  • RocketMQ-生产常见问题汇总
  • 成都网站托管外包施工企业科技宣传片
  • 小厂 Java 面试,难度怎么样?
  • Webpack5 第一节
  • 【深入理解JVM】常见的垃圾回收器
  • 东莞企业建设网站官网有限公司百度一下百度网页版主页