51

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.

Community
  • 1
  • 1
NeilMonday
  • 2,680
  • 2
  • 25
  • 29
  • 8
    This is a cool question – Caffeinated Sep 11 '12 at 21:41
  • 4
    This is a **very** interesting question, but I think is answered here: http://stackoverflow.com/questions/1632600/memory-layout-c-objects and here: http://stackoverflow.com/questions/422830/structure-of-a-c-object-in-memory-vs-a-struct – fableal Sep 11 '12 at 21:43
  • 5
    Uhm... like a bunch of 0s and 1s... – David Rodríguez - dribeas Sep 11 '12 at 21:50
  • 4
    There is a whole book on the matter: [Inside the C++ Object Model](http://www.amazon.com/Inside-Object-Model-Stanley-Lippman/dp/0201834545). Consider that no matter how much information is present in the answers, there are many more things to learn. – David Rodríguez - dribeas Sep 11 '12 at 22:46
  • 1
    I wonder what other question(s) is the culprit/reason for marking this question as duplicate...the two "possible duplicates" are _not_ duplicates of this one (i.e. "structure of a C++ object in memory vs a struct" does not address the OP's question on how functions are laid out, and "memory layout c++ objects" was closed as "too broad" and doesn't have any extremely helpful answers)... – villapx Mar 07 '16 at 15:31

5 Answers5

26

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.

tenfour
  • 36,141
  • 15
  • 83
  • 142
  • 4
    To be pedantic, member functions don't "receive a pointer to `this`". Rather, it's the other way round. Member functions have an implicit instance argument, and within the function body, `this` is a pointer to that instance. – Kerrek SB Sep 11 '12 at 21:56
  • 2
    Even with that description, it's still correct to say the function receives the `this` pointer. It's an argument passed through `ecx` as opposed to the stack. Or maybe I didn't understand you. – tenfour Sep 11 '12 at 22:04
  • It's just an all-to-common mental shortcut that gets people into trouble later on when they're trying to understand member function overload resolution. It's not strictly important here, but I thought I point out the way the language defines member functions. – Kerrek SB Sep 11 '12 at 22:11
  • 1
    If the class includes a vtable, there will be a pointer to the vtable in the memory layout somewhere. If there's multiple inheritance there may be multiple vtables and multiple pointers. It's important to note that the vtable isn't part of each object, only a pointer to it. – Mark Ransom Sep 11 '12 at 22:42
9

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.

Zdeslav Vojkovic
  • 14,391
  • 32
  • 45
7

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.

paddy
  • 60,864
  • 6
  • 61
  • 103
3

First thing to note is that in C++ the term "object" includes things like integers.

Next thing is, structures are laid out pretty much how you'd expect. One member following the next in memory with an undefined amount of padding between.

When a class inherits from another then the class will start with its base class, which in turn may start with a base class of its own. Thus Derived* and Base* will be the same value in cases of single inheritance. Following the base's area (its members) will be the derived class's members in turn, with an undefined amount of padding between them.

When a class inherits from more than one base then things become a little different. The base areas are laid out in memory sequentially. Base1 followed by Base2, etc...after which the derived class's members are laid out in turn with an undefined amount of padding between them.

If the object is of a POD class then it is guaranteed that the first member in the class will be at the location in memory the object resides. This means that Class* and Class->firstMember* will be the same value. I don't believe this applies to non-POD entities.

In the case of polymorphic classes, those with virtual functions, an additional secret member will be created called the vtable. This isn't guaranteed by anything in the standard, but is pretty much the only way to do it and follow the rules that are. Each class has this, so if your class has bases then it will have its table and you'll have yours for additional functions.

All member functions will have their names mangled and parameters modified to accept this as the first argument. This happens behind the scenes as the compiler builds stuff. Virtual functions will be pointed at by the vtable. Non-virtuals will simply be resolved statically and used directly.

Static members are not members of the object created by a class. A static member is simply a global variable with different scope.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
0

It will have its member variables laid out, and also a virtual function table if it is polymorphic which will include a list of pointers to the functions that its virtual methods are actually associated with.

Static means just one copy.

djechlin
  • 59,258
  • 35
  • 162
  • 290
  • 1
    Typically each object doesn't contain a table of function pointers, but a pointer (for each polymorphic subtype) to a table. The tables themselves are shared between all objects of the same dynamic type, saving memory. And the tables contain more than just function pointers, they also require the adjustment between a subtype pointer and the pointer type expected for the hidden `this` parameter of the function. – Ben Voigt Sep 11 '12 at 21:50