You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

64位系统下C++类内存对齐疑问:char后接string为何padding更少?

C++类内存对齐:char后接string与double的sizeof差异解析

在64位操作系统中,C++编译器通常通过内存填充(padding)优化类成员的内存布局,减少CPU访问周期。但遇到如下两种情况时,sizeof结果出现差异:

  • 当类成员为int i、int j、char name、string s时,预期char name会被填充7字节,使后续string按8字节块读取,sizeof应为40,但实际返回36。
  • 当把string s替换为double d时,char name会被填充7字节,sizeof为24。

对应的测试代码:

#include <iostream>
using namespace std;

class emp{
public:
    int i;            // 占4字节
    int j;            // 占4字节
    char name;        // 预期填充7字节(实际填充3字节)
    string s;         // 占24字节
    // double d;      // 占8字节(替换string后)
};

int main()
{
    emp e1;
    cout << sizeof(e1);
}

核心原因:不同类型的对齐要求不同

内存对齐的核心规则有两条:

  1. 每个成员的起始地址必须是其对齐要求值的整数倍。
  2. 整个类的总大小必须是所有成员中最大对齐要求值的整数倍。

1. double的对齐规则(导致sizeof=24)

  • double是基本类型,在64位系统中对齐要求固定为8字节(等于自身大小),CPU对未对齐的double访问会有严重性能损失,甚至在部分架构下无法访问。
  • int i+int j共占8字节,char name占1字节(起始地址8)。为了让后续double d的起始地址满足8字节对齐,char name后需要填充7字节,让d从地址16开始。
  • 总大小计算:4+4+1+7+8=24,24是最大对齐值8的整数倍,无需额外填充,最终sizeof为24。

2. std::string的对齐规则(导致sizeof=36)

  • std::string是自定义类类型,其对齐要求取决于编译器实现和目标架构:
    • 在x86_64架构下,CPU允许指针的未对齐访问(仅损失少量性能,无访问错误)。因此你的编译器可能将std::string的对齐要求设置为4字节(而非8字节),以节省内存空间。
  • int i+int j共8字节,char name占1字节(起始地址8)。为了让string s的起始地址满足4字节对齐,char name后仅需填充3字节,让s从地址12开始。
  • 总大小计算:4+4+1+3+24=36,36是最大对齐值4的整数倍,无需额外填充,最终sizeof为36。

总结差异根源

  • double作为基本类型,对齐要求是强制的8字节,编译器必须严格按此填充。
  • std::string作为自定义类型,其对齐要求具有灵活性,编译器可在架构允许的前提下,选择更低的对齐值以节省内存,这就是两种场景下sizeof结果不同的核心原因。

内容的提问来源于stack exchange,提问作者archana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 06:45:04