What does an object look like in memory? [duplicate]

Possible Duplicate:
Structure of a C++ Object in Memory Vs a Struct
memory layout c++ objects

This is probably a really dumb question, but I will ask anyway. I am curious what an object looks like in memory. Obviously it would have to have all of its member data in it. I assume that functions for an object would not be duplicated in memory (or maybe I am wrong?). It would seem wasteful to have 999 objects in memory all with the same function defined over and over. If there is only 1 function in memory for all 999 objects, then how does each function know who's member data to modify (I specifically want to know at the low level). Is there an object pointer that gets sent to the function behind the scenes? Perhaps it is different for every compiler?

Also, how does the static keyword affect this? With static member data, I would think that all 999 objects would use the exact same memory location for their static member data. Where does this get stored? Static functions I guess would also just be one place in memory, and would not have to interact with instantiated objects, which I think I understand.


Static class members are treated almost exactly like global variables / functions. Because they are not tied to an instance, there is nothing to discuss regarding memory layout.

Class member variables are duplicated for each instance as you can imagine, as each instance can have its own unique values for every member variable.

Class member functions only exist once in a code segment in memory. At a low level, they are just like normal global functions but they receive a pointer to this. With Visual Studio on x86, it's via ecx register using thiscall calling convention.

When talking about virtual functions, polymorphism, then the memory layout gets more complicated, introducing a "vtable" which is basically a bunch of function pointers that define the topography of the class instance.


As you suspect, the data members (fields) are laid out sequentially. This also includes the fields of base classes.

If the class (or one of its base classes) contain any virtual methods, the layout typically starts with vptr, i.e a pointer to a virtual table (or vtable) which is a table of pointers to function implementations related to that class. Please note that this is not defined by standard, but AFAIK all current compilers use this approach. Also, with multiple inheritance it gets more hairy, so let's ignore it for the moment.

+-----------+
|  vptr     |  pointer to vtable which is located elsewhere
+-----------+
|  fieldA   |  first member
|  fieldB   |  ...
|  fieldC   |
|  ...      |
+-----------+

Fields can take more space then the sum of their individual sizes, which depends on packing (e.g. 1 byte packing ensures there are no gaps, but is less efficient than the 4 or 8 byte packing with regard to performance).

Member functions (non static) receive the pointer to the object, but how this is done is implementation and platform specific, e.g. on x86 architecture, the pointer is often passed via ecx register. This is also not defined by the standard.

Static functions are similar to global functions, and they operate on static class fields (shared for all instances of a class) which are located in the data segment.


You've asked a few questions here...

Layout

All the non-static members are organised in memory much like a struct. There may be padding if the compiler chooses to put any in. If you have an array of objects, it's just like an array of structs

Static members

Are stored separately, obviously. One copy.

Function calls

There's a little magic going on behind the scenes for classes. When you call a member function it is much like any other function except it has a different calling convention. Effectively, this inserts the object's pointer (this) into the parameter list.

[edit: the code for the function itself is not stored with your object -- this allows you to do fun things like delete this and continuing execution of a member function provided you no longer access the object you just deleted].

When you have overloaded or polymorphic functions, things get a little more magical. This article is an explanation that I googled up in about 5 seconds. I'm sure there are many more. I've never much concerned myself with the internals of object calls, but it's always nice to know.

You should try the exercise of making a class exhibiting all these different aspects and look at the assembly generated in each case. I have done that before when tuning some time-critical code.