数据成员/代码指针偏移量

时间:2013-03-20 16:35:18

标签: c++ pointers memory memory-management

有人可以帮助我理解以下引用,因为我没有得到它:

  

如果偏移量为,则访问数据成员的代码更紧凑   相对于结构或类的开头的成员较少   比128.例如:

class S2{
    public:
    int a[100];   //400 bytes. first byte at 0, last byte at 399
    int b;        //4 bytes.   first byte at 400, last byte at 403
    int ReadB() {return b;}
};
     

b的偏移量为400。任何通过a访问b的代码   指针或成员函数如ReadB()需要添加4个字节   偏移到指针。 如果a和b交换,则两者都可以   使用1字节有符号整数偏移量访问

这个1字节的值来自哪里?如果a和b被交换,b将从字节0开始,a将从字节4开始?

编辑:我的错误,数组大小应该是100

3 个答案:

答案 0 :(得分:4)

[原始问题从a[400]更改为a[100]后已编辑。]

他们的观点是正确的:

  • S2结构中,a[100]是100个4字节整数;所以实际上是400字节长。因此a偏移0到399. b(再次是一个4字节的int)将被放置(至少)偏移量为400-403:

    Offset  data
    000-399 a[0]-a[99] inclusive
    400-403 b
    
  • 如果您要更换ab的顺序,a的偏移量将为0-3,而b将为4-403:

    Offset  data
    000-003 b
    004-403 a[0]-a[99] inclusive
    
  • 在这两种情况下,访问b将使用16位偏移,即使在数组的早期,由于可能需要的偏移范围。仅在第二种情况下,可以使用8位偏移(取决于CPU)来访问a。这可以更快(取决于CPU)。所有这些都是在存储类的开始位置和存储变量的位置之间存储偏移量所需的位数。

希望这会有所帮助。我假设这里有4个字节的int(这很常见,但不是通用的),因为我认为原始引用它。

答案 1 :(得分:4)

他们试图指出的是 bytes 中从结构开始到b成员的偏移是> 255,因此无法通过向基址指针添加单个8位来计算。需要更多位:

Offset           Member
0                a    // offset always zero
100*sizeof(int)  b    // offset guaranteed to be at 100*sizeof(int)

撤消字段顺序

0                b    // offset always zero
sizeof(int)*     a    // offset always sizeof(int) + potential padding

在第一种情况下访问b需要基址指针+一个需要至少16位偏移的长度值(假设您的最小实体是8位)。在第二种情况下,ba都在适合8位的结构的基址的偏移内。

我觉得有点误导作者并没有提到潜在的成员填充。

编辑已更新,以反映OP对成员b的400到100个阵列广告位的更改。应该注意的是,如果这是一个具有16位实现int值的被破坏的嵌入式系统,那么作者认为这是错误的。在这种情况下,数组将是100 * 2 - 字节宽,这仍然允许8位偏移量到达第二个成员。对于具有4字节(或更大)实现int值的系统,作者指出是有效的。

答案 2 :(得分:0)

它正在谈论存储偏移所需的空间。在给出的示例中,a位于偏移0(需要1个字节来表示),b位于偏移400 * sizeof(int)(实际上可能需要4个字节)。如果交换它们,则a位于偏移0(1字节),b位于偏移4(1字节)。