请问什么是对齐指针?
这意味着指向的地址能被某个因子整除。
有时候会用到术语“自然对齐”,通常指需要将具有自然对齐属性的对象放置在其大小所能整除的地址上。
对齐有时非常重要,因为许多硬件相关的东西会对这种对齐施加限制。
例如,在经典的SPARC 架构(以及经典的ARM 架构,我想是)中,你无法从奇数地址读取大于一个字节的整数。试图这样做将立即使程序停止并报告总线错误。在 x86 架构中,CPU 硬件会处理这个问题(通过根据需要进行多次访问来访问缓存或内存),尽管可能会花费更长的时间。类似 RISC 的架构通常不会为你处理这些问题。
这些事情也可能会影响填充,例如在结构体字段之间插入虚拟数据以维持对齐。一个像这样的结构体:
struct example
{
char initial;
double coolness;
};
很可能会在字段之间有7个字节填充,以使 double
字段对其偏移量可整除自身大小(我假设为8)。
当以二进制方式查看时,对齐到n字节的地址将其log2(n)最低有效位设置为零。例如,需要32字节对齐的对象将具有正确对齐的地址,该地址以(二进制)00000结尾,因为log2(32)为5。这也意味着可以通过清除所需数量的位来强制地址对齐。
补充一下unwind所说的,这是我最近在一个任务中使用的struct
:
struct infosale {
int noseq;
char salesman[30];
char product[11];
int count;
};
struct
的大小为(4+30+11+4=)49
字节,但实际上与sizeof
相比为52
。因为noseq
是4
字节+ salesman
是32
字节(对齐)+ product
是12
字节(对齐),而count
是4
字节,因此总共是52
字节。它是指向“对齐”地址的指针。对齐是指地址是某个值的倍数,通常是所指向的东西(如果是原始类型)的大小,或者需要这种对齐的某些数据成员的大小。
通常情况下,您无需担心这一点;内存分配函数将确保它们提供给您的内存被正确对齐。只有在开始使用指针转换来进行不安全操作时,您才开始担心对齐问题。
正如其他人之前提到的,这意味着您的指针可以被某个字节数均匀地整除。
要检查指针是否对齐,您可以执行以下操作:
isaligned = !( (long)pointer % bytes );
bool isAligned = ((reinterpret_cast<size_t>(pointer) % sizeof(*pointer)) == 0);
。 - MSalters对齐指针是指可以通过添加常量及其倍数来访问相邻内存位置的指针。
例如:char a[5] = "12345";
这里,如果您每次将字符大小与a
相加,则a
是一个常量指针,您可以访问下一个字符,即:
a
+sizeofchar 将访问2
a
+( sizeofchar*2 ) 将访问3
等等
同样地,如果您按位访问变量值。