Fadecomic
Fadecomic

Reputation: 1268

Striding across members of a vector of structures

Is there an easy way to stride through an STL vector of structures by member? In other words, if I have a struct like this:

struct foo {
    double x, y, z;
};

in a vector std::vector<foo> bar(20), can I stride across the array picking out x from each struct?

I've tried this, but it does not seem to work:

for (int i=0; i<20; ++i)
{
   double xx = (&bar[0].x + i*sizeof(bar[0]))->x;
}

Why doesn't that work? Does sizeof(bar[0]) not account for the padding between structs?

Note: I realize this is a really silly way to access x in a loop, but this loop is just an experiment to see if the stride works or not.

If it helps, I want to do this so I can pass bar to a library routine that accepts a pointer and a stride as constructor parameters to its own internal datatype. I could, of course, convert my code from AoS to SoA, but I don't want to do that unless I absolutely have to.

Upvotes: 1

Views: 427

Answers (3)

P-Gn
P-Gn

Reputation: 24581

&bar[0].x is a pointer to double. To add the appropriate shift, you would need to cast it into char*, then double* again.

     double xx = *reinterpret_cast<double*>(reinterpret_cast<char*>(&bar[0].x) + i*sizeof(bar[0]));

In anycase, you should really consider using standard algorithms for your purpose.

Upvotes: 0

Andriy
Andriy

Reputation: 8594

&bar[0].x is a pointer to double. You're adding i*sizeof(bar[0]) to it.

The effect is that the address stored in the pointer increases by i*sizeof(bar[0])*sizeof(double) which is not what you expect.

A correct expression is

&bar[0].x + i*sizeof(bar[0])/sizeof(double)

Upvotes: 1

Jerry Coffin
Jerry Coffin

Reputation: 490048

I think I'd compute the stride directly instead, using something like:

struct point {
    double x, y, z;
};

int main() {
    point points[2];

    std::cout << "stride = " << (char *)(&(points[1].x)) - (char *)(&(points[0].x)) << "\n";
}

Upvotes: 1

Related Questions