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

C++ 数据成员/代码指针偏移量,c++,pointers,memory,memory-management,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。

有人能帮我理解下面的引语吗,因为我没有得到它:

如果 相对于结构或类开头的成员较少 超过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

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

他们的观点是正确的:

  • 在现有的
    S2
    结构中,
    a[100]
    是100个4字节整数;实际上是400字节长<因此,代码>a的偏移量为0到399<代码>b(同样是4字节整数)将(至少)放置在400-403的偏移量处:

    Offset  data
    000-399 a[0]-a[99] inclusive
    400-403 b
    
  • 如果要交换
    a
    b
    的顺序,
    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字节整数(这很常见,但不是通用的),因为我认为原始引用了它。

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

他们试图指出的是,从结构开始到
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位)。在第二种情况下,
b
a
都在适合8位的结构的基址偏移量内

我发现这有点误导,作者至少没有提到潜在的成员填充


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

至于我知道数据成员在C中类似地排列,对于C++ + @ USEXXX,这是可能的,但是这个问题是关于C++的。C中没有
class
int
s不一定是4字节。很抱歉,数组大小应该是100。我打错了-我编辑了我的问题。@NeilTownsend:我想在你的第二个公告点中,你得到了
a
b
b
是单个int,而
a
是数组。除非您也交换了名称,但这只是混淆而已。简言之,如果我理解的话,我们要看的是第一个数据成员和最后一个数据成员的字节边界之间的距离(以字节为单位)?重新排列意味着b和a之间的距离小于256-也就是说,我们可以使用一个字节作为它们的地址偏移量?@user997112:是的,你知道了。问题中提到的1字节是保存偏移量所需的内存量。如果两个偏移量都小于256,那么两个偏移量的值可能都保存在一个字节中。我想你的意思是“a在偏移量4处?”所以我们要说的是,1字节,即2^8和256,将允许我们引用数据成员字节边界的位置?如果我们有第三个数组,我们可能需要一个短的整数指针来确保引用的字节偏移量超过256?除了关于对齐的明显缺失点之外,第一个成员不一定保证偏移量为0。如果类型或其任何可传递的基类型具有虚拟成员,则第一个成员前面将有一个指向vtable的指针。如果不检查标准,我想这意味着无法保证数据成员的偏移量是多少,因为标准本身并不涉及vPointer或vtables。@幸好,bitmask标准至少明确了初始成员:事实上,唯一保证始终具有已知偏移量的偏移量。根据C++11§9.2,p20:“指向标准布局结构对象的指针,使用重新解释转换进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向其所在的单元),反之亦然。[注意:因此,标准布局结构对象中可能会有未命名的填充,但不会在其开头,这是实现适当对齐所必需的。”IIRC,这仅适用于POD。具有虚拟成员函数的类的第一个成员肯定没有偏移量零。@位掩码正确。我误解了您最初的评论,对此我深表歉意