【问题标题】:What exactly is an 'aligned pointer'?究竟什么是“对齐指针”?
【发布时间】:2011-05-18 09:35:30
【问题描述】:

有人能告诉我对齐指针的真正含义吗?

【问题讨论】:

    标签: c++ c memory-alignment


    【解决方案1】:

    表示被指向的地址可以被某个因子整除。

    有时使用术语“自然对齐”,这通常意味着具有自然对齐的对象需要放置在可被对象大小整除的地址。

    对齐有时非常重要,因为许多与硬件相关的事情都对这种对齐施加了限制。

    例如,在经典的SPARC 架构上(我认为也在经典的ARM 上),您无法从奇数地址读取大于一个字节的整数。尝试这样做会立即因总线错误而停止您的程序。在 x86 架构上,CPU 硬件会处理这个问题(通过根据需要对缓存和/或内存进行多次访问),尽管它可能需要更长的时间。 RISC:ier 架构通常不会为您执行此操作。

    类似的事情也会影响填充,即在 e.g. 之间插入虚拟数据。结构字段以保持对齐。像这样的结构:

    struct example
    {
      char initial;
      double coolness;
    };
    

    很可能最终会在字段之间填充 7 个字节,以使 double 字段在可被其自身大小(我假设为 8)整除的偏移量上对齐。

    当以二进制形式查看时,与 n 个字节对齐的地址将其 log2(n) 最低有效位设置为零。例如,需要 32 字节对齐的对象将具有以(二进制)00000 结尾的正确对齐地址,因为 log2(32) 为 5。这也意味着可以通过清除所需数字来强制地址对齐位。

    【讨论】:

    • @unwind:OOC,你知道有没有说因素是 odd 的实现?
    • "aligned to n bytes" 应该读作"aligned to n bits ",因为 log2(1) = 0。你的意思是 log2(8) = 3。
    • @Axel:我不关注...是的,log2(1) 为 0,需要 1 字节对齐的对象不需要任何 LSB 强制为零。我添加了一个例子,我希望它更清楚。你还觉得不对吗?
    • 请注意,酷度仍然不一定对齐。例如 struct X { char a;示例 b; };这就是为什么在需要时很难保证对齐的原因,以及为什么在这种情况下您经常需要显式使用对齐的 malloc 函数来保证它是对齐的。
    • @tenfour: coolness 实际上会对齐。编译器将为struct example 提供与所有成员兼容的对齐要求。假设double 是8 字节对齐的,这意味着struct example 也是8 字节对齐的。因此sizeof(X)==24ab 之间还有另外7 个字节的填充。反过来,X 继承了相同的 8 字节对齐要求。
    【解决方案2】:

    为了补充unwind 的解释,这是我最近在作业中使用的struct

    struct infosale {               
        int   noseq;                
        char  salesman[30];         
        char  product[11];          
        int   count;                
    };                               
    

    您可能期望这个struct 的大小为(4+30+11+4=)49 字节,但实际上与sizeof 相比,它是52。因为noseq4字节+salesman32字节(对齐)+product12字节(对齐)和count4字节,因此52字节。 /p>

    【讨论】:

    • 您的数学已关闭。另外,我怀疑填充是拆分的,而不是直接在最后一个 int 之前添加 3 个必要的字节填充。
    • 我已经用 GCC(不记得版本)在 C 中对其进行了测试,这就是调试器当时报告的内容。我必须审查以确认。但是,我很确定编译器不喜欢奇数地址,并且会将变量对齐到偶数偏移量;所以它会填充,除非明确指示不要。 (我用 C 编码已经有一段时间了!)
    • 抱歉不清楚:您的第一个总和是 49 而不是 48,我很想知道您在哪个编译器上测试它,它像 int 一样对齐 char 数组。
    • @Deduplicator:实际上,编译器尝试为大型 char 数组成员提供与动态分配相同的对齐保证,这并不罕见。 char 数组(也就是说,对齐对于任何适合的原始数据类型都足够好)
    • @Deduplicator:嗯,s/unusual/unreasonable/
    【解决方案3】:

    取决于上下文,但可能是指针本身对齐,也可能是指针指向的对象对齐。

    '对齐'表示某个对象存储在某个地址是某个常数的倍数。例如。对于 32 位整数,这几乎总是 4。这是因为一个字节是 8 位:4*8 = 32 位。如果对象存储在对齐的地址,处理器通常可以更快地访问内存,或者对于某些处理器,甚至不可能进行非对齐访问。

    【讨论】:

      【解决方案4】:

      它是一个指向“对齐”地址的指针。对齐的意思是地址是某个值的倍数 - 通常是它将指向的任何类型的事物(如果是原始类型)或某些需要这种对齐的数据成员的大小。

      通常你不必担心这个;内存分配函数将确保它们给你的内存是正确对齐的。在开始使用指针强制转换做不安全的事情时,您开始担心对齐问题。

      【讨论】:

        【解决方案5】:

        正如人们在我之前提到的那样,这意味着您的指针可以被一定数量的字节整除。

        要检查您的指针是否对齐,您可以这样做:

        isaligned = !( (long)pointer % bytes );
        

        现在,如果“pointer”与“bytes”字节对齐,则“isaligned”为真。

        【讨论】:

        • 实际上,你不能,你的编译器会告诉你。你可以试试bool isAligned = ((reinterpret_cast<size_t>(pointer) % sizeof(*pointer)) == 0);
        • 是的,没错。您不能对指针进行模运算,因此您必须将其转换为更合适的值。我会解决的!
        【解决方案6】:

        对齐指针是指具有相邻内存位置的指针,可以通过添加一个常量及其倍数来访问

        char a[5] = "12345";

        这里a是常量指针,如果你和char的大小每次你可以访问下一个字符,也就是,

        a+sizeofchar 将访问2

        a+( sizeofchar*2 ) 将访问3 以此类推

        类似地,如果您逐位访问变量值。

        【讨论】:

          猜你喜欢
          • 2019-01-15
          • 1970-01-01
          • 2014-10-28
          • 2012-08-27
          • 2010-11-12
          • 2011-03-18
          • 2011-01-22
          • 1970-01-01
          相关资源
          最近更新 更多