I have the following class:
struct xyzid{
uint16_t i;
uint16_t z,y,x;
};
std::vector<xyzid> example;
(...) // fill example
uint16_t* data = reinterpret_cast<uint16_t*>(example.data());
Can I now be sure that my pointer data
is basically such that the first 16 bits refer to i
, then z
, y
, x
, before moving to the next element? Or, is it not guaranteed that the order of declaration in my struct is preserved within my std::vector
container?
CodePudding user response:
The vector
contains an allocated array of structs. The data
pointer points at the 1st struct in the array. The structs in the array are stored sequentially in memory. And the fields of each struct are also stored sequentially in memory, in the order that they are declared. So yes, the array will consist of the 1st struct fields i
, then z
, then y
, then x
, then the 2nd struct fields, and so on.
However, what you CAN'T count on is that the 1st struct's z
field will occupy the 2nd 16 bits of memory, or the y
field will occupy the 3rd 16 bits of memory, etc. This is dependent on the struct's alignment padding. If you are expecting the memory to be filled in that way, the only way to guarantee that is to disable all alignment padding between the structs and their fields, by declaring the struct's alignment as 8-bit/1-byte, such as with #pragma pack(1)
or __attribute(packed)
or other similar compiler directive.
But, you really shouldn't rely on this behavior if you can help it. If you absolutely need the memory to have an exact layout, use serialization instead.