C++11 内存对齐 alignof alignas

本文详细介绍了C++中的内存对齐概念,包括为何需要内存对齐、内存对齐的硬件与性能原因,以及C++11如何通过alignof和alignas操作符实现内存对齐。同时对比了C++98/03中不同编译器如MSVC和GCC的内存对齐实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 现象

先看一段代码:

struct s1
{
    char s;
    int i;
};

struct s2
{
    int i;
    double d;
};

cout << "-------basic type" << endl;
cout << "sizeof(char)	" << sizeof(char) << endl;
cout << "sizeof(int)	" << sizeof(int) << endl;
cout << "sizeof(double)	" << sizeof(double) << endl;

cout << endl;
cout << "-------struct" << endl;
cout << "sizeof(s1)	" << sizeof(s1) << endl;
cout << "sizeof(s2)	" << sizeof(s2) << endl;

结果如下:

不同机器环境,可能结果不同,但不影响说明问题。例如,结构体s1中包含一个char和int,那么s1的大小应该是5,但结果是8,s2也是如此,这就涉及到一个概念:内存对齐。

二 内存对齐

1 什么是内存对齐?

看到的一句说明,“数据项仅仅能存储在地址是数据项大小的整数倍的内存位置上”。

2 为什么要内存对齐?

(1)硬件原因,一些硬件平台必须要求内存对齐,否则抛出异常;另外涉及到不同平台的移植问题。

(2)性能原因,对齐后访问效率更高。

三 C++11 内存对齐实现

1 C++11 新引入操作符alignof对齐描述符alignas基本对齐值 alignof(std::max_align_t)

alignas可以接受常量表达式和类型作为参数,可以修饰变量、类的数据成员等,不能修饰位域和用register申明的变量。一般往大对齐。

直接看一段代码(结合上一段代码):

struct s3
{
    char s;
    double d;
    int i;
};


struct s11
{
    alignas(16) char s;
    int i;
};

struct s12
{
    alignas(16) char s;
    int i;
};


// alignof
cout << "-------------------alignof---------------------" << endl;
// 基本对齐值
cout << "alignof(std::max_align_t)	" << alignof(std::max_align_t) << endl;
cout << endl;
cout << "-------basic type" << endl;
cout << "alignof(char)		" << alignof(char) << endl;
cout << "alignof(int)		" << alignof(int) << endl;
cout << "alignof(double)	" << alignof(double) << endl;

cout << endl;
cout << "-------struct" << endl;
cout << "alignof(s1)		" << alignof(s1) << endl;
cout << "alignof(s2)		" << alignof(s2) << endl;
cout << "alignof(s3)		" << alignof(s3) << endl;

cout << endl;
cout << endl;

// alignas
cout << "-------------------alignas---------------------" << endl;
cout << "alignof(s1)		" << alignof(s1) << endl;
cout << "alignof(s11)		" << alignof(s11) << endl;
cout << "alignof(s12)		" << alignof(s12) << endl;

cout << "sizeof(s1)    	" << sizeof(s1) << endl;
cout << "sizeof(s11)	" << sizeof(s11) << endl;
cout << "sizeof(s12)	" << sizeof(s12) << endl;

结果如下:

2 C++11还新增了几个内存对齐的函数,每个函数有特定作用,此处不展开。

std::alignment_of
std::aligned_storage
std::max_align_t
std::align

四 C++98/03 内存对齐实现

此情况下主要是由编译器实现,不同编译器有不同方法。

1 MSVC

__declspec(align(#)),其#的内容可以是预编译宏,但不能是编译期数值

#progma pack

__alignof

2 gcc

  __attribute__((__aligned__((#))))

 __alignof__

 

 

### C++内存对齐的规则及其实现 #### 内存对齐的重要性 在 C++ 编程中,内存对齐是一个重要的概念。合理的内存对齐可以显著提升程序性能、减少内存碎片并增强数据访问效率[^3]。 #### 基本规则 C++内存对齐遵循以下几个基本原则: 1. **基本类型对齐**:每种基础数据类型的地址必须是对齐到其大小的整数倍上。例如,`int` 类型通常占用 4 字节,则它的起始地址应该是 4 的倍数[^1]。 2. **结构体内存对齐**:在一个 `struct` 或 `class` 中,各成员变量按照声明顺序依次排列,并满足各自的数据类型对齐需求。整个结构体的总大小通常是最大成员对齐值的整数倍。 3. **编译器默认对齐方式**:大多数情况下,编译器会选择一种默认的对齐策略(如 `_Alignas`),开发者也可以通过特定指令调整对齐方式。 #### 获取对齐方式的方法 C++ 提供了标准工具用于查询和设置对齐方式。其中,`alignof` 运算符能够返回指定类型的对齐要求(单位为字节数)。需要注意的是,该运算符仅适用于具体的类型而非全局对齐配置[^2]。 #### 示例代码展示 以下是关于如何定义带自定义对齐属性的对象及其验证过程的一个简单例子: ```cpp #include <iostream> #include <type_traits> // 定义具有特殊对齐要求的类 struct alignas(16) AlignedStruct { char c; int i; }; int main() { std::cout << "Alignment of char: " << alignof(char) << " bytes\n"; // 输出 1 byte std::cout << "Alignment of int: " << alignof(int) << " bytes\n"; // 可能输出 4 bytes (取决于平台) // 打印自定义对齐后的 struct 对齐情况 std::cout << "Size of AlignedStruct: " << sizeof(AlignedStruct) << " bytes\n"; std::cout << "Alignment of AlignedStruct: " << alignof(AlignedStruct) << " bytes\n"; return 0; } ``` 上述代码展示了如何使用 `alignas` 关键字强制设定对象的最小对齐边界,同时也演示了通过 `alignof` 查看不同类型实际所需对齐量的方式。 #### 不同架构下的影响 不同硬件架构对待未对齐访问的态度各异。某些处理器(如 ARM 和 SPARC)完全不允许未对齐操作;而另一些像 x86 则允许但会牺牲一定运行速度作为代价[^4]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值