I have a class like this:
class Object {
public:
unsigned char data[8];
// other variables
// functions etc...
};
The question is - are the object members all stored in the same place in memory relative to the object? So if I have an array: Object array[3], given a char pointer
char* data_ptr = array[0].data
, will
data_ptr + (sizeof(Object))
then always point to array[1].data?
(I've read a couple of Q/As about how there might be padding inbetween data members of classes and structs - but I don't think they answer my question.)
Thanks in advance, Ben
sizeof Object
already includes all internal padding of the classObject
. including any padding at its end. Arrays don't allow any additional padding. Therefore it is true thatdata_ptr + sizeof Object
will have the address ofarray[1].data
.However I'm not sure if this is actually allowed. That is, the compiler might be allowed to assume that you never add a value larger than 8 (the size of the member array
data
) toarray[0].data
, and therefore it might apply optimizations that fail if you violate the rules. That is, your code might actually exhibit undefined behavior (which is the standard term for "the compiler is allowed to do anything in this case").However since you are using a pointer to
char
, for which there are more permissive rules (you can do many things withchar*
which you could not do with general types), it may be that it's actually defined behaviour anyway.If the aim of your question is to understand how things are in memory, then it is acceptable.
But if you want to do that for real: What you want to do is actually criminal against all your colleagues.
The proper way to go through collection in C++ is not to use an array, but an std::vector, or another std collection if it is really needed. We shouuld no longer use C arithmetics, but access the items of the vector collection through an iterator. That's the reason of the C++ standard library :-)
There are many factors that decide the size of an object of a class in C++. These factors are: - Size of all non-static data members - Order of data members - Byte alignment or byte padding - Size of its immediate base class - The existence of virtual function(s) (Dynamic polymorphism using virtual functions). - Compiler being used - Mode of inheritance (virtual inheritance)
check here: http://www.cprogramming.com/tutorial/size_of_class_object.html
I think the answer is "Maybe", which means you should not bet on this. Best way would be to play around on your IDE debugger looking up memory addresses. You'll find this could easily get thrown off when you introduce having members and methods that the compiler can optimize. For example any constants or a method that doesn't access any members that could be static. Ex:
I believe this actually gets optimized into the static allocation because I recently learned that this
((Object)NULL).doSomething();
actually works without a SEGFAULT until you introduce a member variable forObject
.Yes, the layout relative to the object's base address will be constant. This is a requirement for the ABI. Any spacing or padding of objects and arrays is also specified by the ABI.