Reputation: 362
I am curious how the memory model works for C++ classes. Specifically, whether I am guaranteed that data members for an object are allocated contiguously. For example, if I have the following code:
class Particle {
public:
Particle(double ix, double iy, double ivx, double ivy);
// Omitted for brevity
private:
double x;
double y;
double vx;
double vy;
};
When I initialize an object will the data members be contiguous in memory or am I better off (for performance) doing something like this:
class Particle {
public:
Particle(double ix, double iy, double ivx, double ivy);
// Omitted for brevity
private:
std::array<double, 4> params
};
I come from a background in Fortran and C programming and I am used to using arrays for fast sequential memory access so I am curious whether one of the above semantics is preferred for fast access when all data members are used consecutively on any call.
Upvotes: 0
Views: 1302
Reputation: 25388
[Meta answer]
am I better off (for performance)...
Why would allocating data members contiguously necessarily improve performance? In fact, because things like double
like to be suitably aligned, the opposite is often true (which is why the compiler doesn't always do it).
Upvotes: 0
Reputation: 264501
The standard guarantees that they will be in that order in memory
(if you took their addresses they would increment).
It does not guarantee that they will be in contiguous memory; but if that is the most optimal layout then they probably will be. Compiler is allowed to add padding between members (it usually does this to make access more efficient (sacrifice space for speed)). If all the members are the same size this is unlikely.
Note: Introducing public/private/protected between them complicates things and may change the order.
Are you better of using an array?
That depends. Would you normally accesses them via an index or via the name? I would say thay 99% of the time the first version you have is better but I can imagine use cases where std::array<>
could be useful (members accessed via an index).
It was suggested in the comments std::vector<>
could also be used. This is true and the standard guarantees the members are in contiguous location, but they may not be local to the object (in a std::array<>
they are local to the object).
Upvotes: 5
Reputation: 1904
Yeah, it's guaranteed that order will by same as in declaration by [class.mem].19
Non-static data members of a (non-union) class with the same access control are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified. Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions and virtual base classes.
Upvotes: 1