7

Suppose I have a simple C++ class,

class Data {

    public: 
         float data[3];         

         void clear() { data[0] = 0.0f; data[1] = 0.0f; data[2] = 0.0f }

}

And a vector of Data's,

std::vector<Data> v(10);

Is it safe to assume that &v[0].data[0] points to an array of 30 floats?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Daniel Fortes
  • 153
  • 1
  • 1
  • 5
  • 3
    Does it point to 30 contiguous `float`? Yes. Does it point to *an array of* 30 `float`? No. There is a difference. It would be far safer to iterate over each `Data`, and then each `data` within that. – Cory Kramer May 11 '15 at 12:50
  • 2
    @Cyber What about padding? – juanchopanza May 11 '15 at 12:57
  • possible duplicate of [c++ memory in array of class objects](http://stackoverflow.com/questions/12025598/c-memory-in-array-of-class-objects) – Cory Kramer May 11 '15 at 13:07
  • I suppose this question is not really interesting, without understanding what the problem is. Do you want to treat the vector as a flat array an index into it? – Shafik Yaghmour May 11 '15 at 13:36
  • 1
    Is it safe? Probably not. But that said, I've written several memory map using programs that rely on behavior like this. Use packing pragmas and compile time sizeof asserts. – Zan Lynx May 11 '15 at 15:19
  • Add a single char to your object and compile for a target architecture with strict alignment rules for floats, and the vector elements will no longer be contiguous (size of vector buffer != size of vector entry * number of entries) If your question is "can I get away with this" my answer is the compiler will probably let you, but I as a co-worker will hunt you down and make you fix your broken code at 3AM when I run into it! – Dale Wilson May 11 '15 at 21:25

1 Answers1

5

From standard

23.3.6.1 Class template vector overview

The elements of a vector are stored contiguously, meaning that if v is a vector where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size()

so &v[0] indeed points to the beginning of 10 continuous Data objects.

but for the layout of Data we have

9.2.13 Class members

Nonstatic data members of a (non-union) class with the same access control (Clause 11) 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 (11). 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 (10.3) and virtual base classes (10.1).

so we cannot be sure that sizeof(Data) == 3*sizeof(float), therefore general answer should be: it's not save to assume 30 continuous floats.

j.holetzeck
  • 4,048
  • 2
  • 21
  • 29
  • That only answers half of the question. They are asking basically if all of the internal arrays are contiguous with each other. – Cory Kramer May 11 '15 at 12:59