遍历带有指针和偏移量的stucts成员的向量,第2部分

时间:2019-01-31 17:15:52

标签: c++ pointers iteration pointer-arithmetic

因此,这是我提出的问题的第二部分,昨天得到了回答。所以今天我要谈谈第二部分。我不确定这是否应该在其他地方,如果主持人想随意移动它。

所以我不会在这里再次提出我的问题,所以请继续阅读第1部分 Iterating through a vector of stucts's members with pointers and offsets

所以我想出了解决这个问题的方法,所以让我发布一个修改后的代码片段,以表示我要解决的问题,

#include <iostream>
#include <vector>

// knows nothing about foo
class Readfoo
{ 
    private:
    int offSetSize;
    char* pchar;

    public:
    void SetPoint(double* apstartDouble, int aoffSetSize)  
    {
        offSetSize = aoffSetSize;
        pchar = static_cast<char*> (static_cast<void*>(apstartDouble));
    };

    const double& printfoo(int aioffset) const
    {
       return *(static_cast<double*> (static_cast<void*>(pchar + aioffset*offSetSize)));
    };
};

// knows nothing about readFoo
struct foo
{ 
    int a[5];
    double b[10];
};

int main() 
{
    // populate some data (choose b [2] or other random entry.).
    std::vector<foo> bar(10);
    for(int ii = 0; ii < bar.size(); ii++) 
        bar[ii].b[2] = ii;

    // access b[2] for each foo using an offset.
    Readfoo newReadfoo;
    newReadfoo.SetPoint(&(bar[0].b[2]), sizeof(foo)/sizeof(char));
    for(int ii = 0; ii < bar.size(); ii++)
        std::cout<<"\n"<<newReadfoo.printfoo(ii);

    return 0; 
}

我认为这是合法的,我想这就是我要问的。从现在开始,从本质上讲,从现在开始,我将对struct foo和向量bar(foos的数组)的“解释”转换为单个字节或char数组。

即在这种解释中,数据结构是char的单个数组,其大小为foo大小乘以bar大小。当我使用整数类型遍历此函数时,我实质上是在移动到某些假设的char元素(第1部分答案中的第4.2点)。然后,printfoo函数将接下来的8个字节合并为一个双精度值以返回。

这是合法的吗,除了超出条形矢量的界限之外,是否有任何原因使它不起作用(我已经对其进行了测试,但尚未失败)?

1 个答案:

答案 0 :(得分:3)

  

这合法吗...

不,不是。

在以下表达式中:

pchar + aioffset*offSetSize

您操纵pchar就像是指向char数组的指针,而不是指向double数组的指针一样。这是未定义的行为:

  

[expr.add]/6

     

对于加法或减法,如果表达式PQ的类型为“ cv T的指针”,其中T和数组元素类型不相似,行为未定义。 [注:尤其是当数组包含派生类类型的对象时,不能将指向基类的指针用于指针算术。 —尾注]

在您的情况下,Ppchar,并且具有指向char的类型指针,但是它指向的数组元素是double


  

...除了移出条形图矢量的界限外,还有什么原因为什么它不起作用(我已经对其进行了测试,但尚未失败。)?

是:Does the C++ standard allow for an uninitialized bool to crash a program?


更进一步:C ++中的指针操作是一个危险信号。 C ++指针操作是一种黑魔法,它将燃烧您的灵魂并消耗您的狗。 C ++提供了许多编写通用代码的工具。我的建议:询问您要实现的目标,而不是解决方案。您会学到很多。