了解对齐概念
Understanding alignment concept
对齐是一个实现定义的整数值,表示给定的对象。
这个概念有点不清楚。例如:
struct B { long double d; };
struct D : virtual B { char c; }
当D是一个完整对象的类型时,它将有一个子对象类型B,因此必须对
long double
进行适当的对齐。
这是什么意思?sizeof(long double)
是在这种情况下介于什么之间的字节数??
大多数CPU都有关于数据存储位置的"首选项"。在读取或写入内存地址时,如果地址与您尝试写入的数据大小不匹配,则操作可能会较慢(或完全非法(。例如,通常要求从可被4整除的地址开始分配4字节整数。
也就是说,存储在地址7
上的int
要么效率较低,要么完全非法,这取决于您的CPU。但是如果它被存储在地址8
,CPU是高兴的。
这就是对齐所表达的:对于任何类型为T
的对象,为了满足CPU的要求,它的地址必须可以被什么整除?">
在C++中,对象的对齐由实现定义(因为如上所述,它取决于CPU架构(。C++只是说每个对象都有对齐,并描述了如何确定复合对象的对齐。
"为long double
对齐"只是意味着必须分配对象,以便将其第一个字节放置在对long double
有效的地址中。如果CPU体系结构将long double
的对齐指定为10(例如(,那么这意味着具有此对齐的每个对象都必须分配在可被10整除的地址上。
我完全理解你的不确定性。这可能是我见过的解释什么是对齐的最糟糕的尝试之一
从实际的角度考虑。
00100000 64 65 66 61 75 6c 74 0a 31 0a 31 0a 31 0a 31 0a |default.1.1.1.1.|
00100010 32 0a 31 0a 33 0a 30 0a 31 0a 34 0a 32 33 0a 31 |2.1.3.0.1.4.23.1|
00100020 39 0a 31 37 0a 35 0a 32 36 0a 32 34 0a 33 0a 38 |9.17.5.26.24.3.8|
00100030 0a 31 32 0a 31 31 0a 31 30 0a 31 34 0a 31 33 0a |.12.11.10.14.13.|
00100040 38 32 0a 38 33 0a 38 34 0a |82.83.84.|
这是任意数据的六进制转储。假设此数据已加载到内存中的地址,如图所示。由于地址是用十六进制写的,所以很容易看到位对齐。
0x100000和0x100001处的数据可以作为16位对齐值进行访问(使用合适的CPU指令或通过C指针引用进行16位数据访问(。但是数据0x100003和0x100004没有对齐—它跨越2和3处的16位字以及4和5处的16比特字。前者是16位对齐的,而后者不是。
同样,0x100030.100037处的64位(8字节(值也是64位对齐的。但0x100038之前的一切都不是。
对准特性是由于存储器总线硬件将存储器访问组织成总线周期。16位数据总线能够在一次操作中获取8位或16位,但后者仅在地址为偶数时(最低有效地址位为零(。允许"奇数对齐"的CPU执行两个连续的总线周期(一个偶数,另一个奇数(来完成操作。其他CPU只是针对不对齐的总线周期发出故障。
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 64位机器上的C++内存对齐
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 使 std::vector 分配对齐内存的现代方法
- C++ cout 将双精度对齐到精度 2 并正确对齐
- 在 64 位边界上对齐C++结构数组?
- 使用 g++7 构建的代码在访问未对齐的内存时崩溃
- 在 capnp FlatArrayMessageReader 的对齐内存缓冲区中接收 zmq 消息
- 是否值得对齐变量?
- 初始化派生结构的基部分/意外打包派生结构字段以对齐基结构的间隙
- 对齐和对齐的实际用例C++关键字
- 如何减少代码的运行时间以对齐文本?
- 指向包含对齐 C 结构C++类的 C 指针的对齐问题
- Linux C++ 中的页面对齐内存分配
- C++ 类层次结构中的"对齐"是什么意思?
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 不了解C 内存对齐
- 了解对齐概念