C/C++对齐问题

C11 的对齐特性比用位填充字节更自然,它们还代表了C在处理硬件相关问题上的能力。
在这种上下文中,对齐指的是如何安排对象在内存中的位置。
例如,为了效率最大化,系统可能要把一个 double 类型的值储存在4 字 节内存地址上,但却允许把char储存在任意地址。大部分程序员都对对齐不 以为然。但是,有些情况又受益于对齐控制。例如,把数据从一个硬件位置 转移到另一个位置,或者调用指令同时操作多个数据项。
_Alignof运算符给出一个类型的对齐要求,在关键字_Alignof后面的圆括 号中写上类型名即可:

size_t d_align = _Alignof(float);

假设d_align的值是4,意思是float类型对象的对齐要求是4。也就是说,4是储存该类型值相邻地址的字节数。一般而言,对齐值都应该是2的非负整数次幂。较大的对齐值被称为stricter或stronger,较小的对齐值被称为 weaker。
可以使用_Alignas 说明符指定一个变量或类型的对齐值。但是,不应该要求该值小于基本对齐值。例如,如果float类型的对齐要求是4,不要请求其对齐值是1或2。该说明符用作声明的一部分,说明符后面的圆括号内包含 对齐值或类型:

_Alignas(double) char c1;
_Alignas(8) char c2;
unsigned char _Alignas(long double) c_arr[sizeof(long double)];
// align.c -- 使用 _Alignof 和 _Alignas (C11)
#include <stdio.h>
int main(void)
{
double dx;
char ca;
char cx;
double dz;
char cb;
char _Alignas(double) cz;
printf("char alignment:  %zd\n", _Alignof(char));
printf("double alignment: %zd\n", _Alignof(double));
printf("&dx: %p\n", &dx);
printf("&ca: %p\n", &ca);
printf("&cx: %p\n", &cx);
printf("&dz: %p\n", &dz);
printf("&cb: %p\n", &cb);
printf("&cz: %p\n", &cz);
return 0;
}
该程序的输出如下:
char alignment: 1
double alignment: 8
&dx: 0x7fff5fbff660
&ca: 0x7fff5fbff65f
&cx: 0x7fff5fbff65e
&dz: 0x7fff5fbff650
&cb: 0x7fff5fbff64f
&cz: 0x7fff5fbff648

在我们的系统中,double的对齐值是8,这意味着地址的类型对齐可以 被8整除。以0或8结尾的十六进制地址可被8整除。这就是地址常用两个 double类型的变量和char类型的变量cz(该变量是double对齐值)。因为char 的对齐值是1,对于普通的char类型变量,编译器可以使用任何地址。
在程序中包含 stdalign.h 头文件后,就可以把 alignas 和 alignof 分别作为 _Alignas 和_Alignof的别名。这样做可以与C++关键字匹配。
1184
C11在stdlib.h库还添加了一个新的内存分配函数,用于对齐动态分配的 内存。该函数的原型如下:

void *aligned_alloc(size_t alignment, size_t size);

第1个参数代表指定的对齐,第2个参数是所需的字节数,其值应是第1 个参数的倍数。与其他内存分配函数一样,要使用free()函数释放之前分配 的内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值