Memory Layout of C++ Object
Tags: cpp, programming, tutorial, computerscience
Published: 2020-05-18 03:17:48

<!-- wp:paragraph -->
<p>In this article, we will see the memory layout of different C++ Object. And how different storage &amp; access specifiers affect this memory footprint. I am not going to discuss compiler augmented code, name mangling &amp; working of any C++ mechanism related to memory as it is compiler &amp; architecture-dependent. To keep this further simple, I have considered the standard <a rel="noreferrer noopener" aria-label="stack growth direction (opens in a new tab)" href="http://www.vishalchovatiya.com/how-c-program-convert-into-assembly/" target="_blank"><span style="color:#0820f0" class="color">stack growth direction</span></a> i.e. downwards. </p>
<!-- /wp:paragraph -->

> /!\\\: Originally published @ [www.vishalchovatiya.com](http://www.vishalchovatiya.com/).

<!-- wp:paragraph -->
<p>So, in nutshell, it's just all about <strong><em>"How different objects are laid out in memory?"</em></strong></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Memory Layout of Simple &amp; Non-Polymorphic Object in C++</h3>
<!-- /wp:heading -->

```c++
class X {
    int     x;
    float   xx;

public:
    X() {}
    ~X() {}

    void printInt() {}
    void printFloat() {}
};
```

<!-- wp:list -->
<ul><li>Memory layout: </li></ul>
<!-- /wp:list -->

<!-- wp:enlighter/codeblock {"linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">      |                        |          
      |------------------------| &lt;------ X class object memory layout
      |        int X::x        |
      |------------------------|  stack segment
      |       float X::xx      |       |   
      |------------------------|       |
      |                        |      \|/
      |                        |    
      |                        |
------|------------------------|----------------
      |         X::X()         | 
      |------------------------|       |   
      |        X::~X()         |       |
      |------------------------|      \|/
      |      X::printInt()     |  text segment
      |------------------------|
      |     X::printFloat()    |
      |------------------------|
      |                        |            </pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:list -->
<ul><li>In conclusion of the above example, only data members got the space in the stack. That too as the same order of their declarations. Because this is guaranteed by most of the compilers, apparently. </li><li>In addition, all other methods, constructor, destructor &amp; <a rel="noreferrer noopener" aria-label="compiler augmented code  (opens in a new tab)" href="http://www.vishalchovatiya.com/inside-the-cpp-object-model/" target="_blank"><span style="color:#2d04f8" class="color">compiler augmented code </span></a>goes into the <a rel="noreferrer noopener" aria-label="text segment (opens in a new tab)" href="http://www.vishalchovatiya.com/how-c-program-stored-in-ram-memory/" target="_blank"><span style="color:#2e07ee" class="color">text segment</span></a>. These methods are then called &amp; passed <code>this</code> pointer implicitly of calling object in its 1st argument which we have already discussed in <a rel="noreferrer noopener" aria-label="this  (opens in a new tab)" href="http://www.vishalchovatiya.com/how-cpp-object-used-internally-in-the-executable/" target="_blank"><span style="color:#4c2bd3" class="color">Inside The C++ Object Model</span></a>.</li></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3>Layout of an Object With Virtual Function &amp; Static Data Member</h3>
<!-- /wp:heading -->

```c++
class X {
    int         x;
    float       xx;
    static int  count;

public:
    X() {}
    virtual ~X() {}

    virtual void printAll() {}
    void printInt() {}
    void printFloat() {}
    static void printCount() {}
};
```

<!-- wp:list -->
<ul><li>Memory layout:</li></ul>
<!-- /wp:list -->

<!-- wp:enlighter/codeblock {"linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">      |                        |          
      |------------------------| &lt;------ X class object memory layout
      |        int X::x        |
stack |------------------------|
  |   |       float X::xx      |                      
  |   |------------------------|      |-------|--------------------------|
  |   |         X::_vptr       |------|       |       type_info X        |
 \|/  |------------------------|              |--------------------------|
      |           o            |              |    address of X::~X()    |
      |           o            |              |--------------------------|
      |           o            |              | address of X::printAll() |
      |                        |              |--------------------------|
      |                        |
------|------------------------|------------
      |  static int X::count   |      /|\
      |------------------------|       |
      |           o            |  data segment           
      |           o            |       |
      |                        |      \|/
------|------------------------|------------
      |        X::X()          | 
      |------------------------|       |   
      |        X::~X()         |       |
      |------------------------|       | 
      |      X::printAll()     |      \|/ 
      |------------------------|  text segment
      |      X::printInt()     |
      |------------------------|
      |     X::printFloat()    |
      |------------------------|
      | static X::printCount() |
      |------------------------|
      |                        |</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:list -->
<ul><li>As you can see above, all non-static data members got the space into the stack with the same order of their declaration which we have already seen in the previous example.</li><li>And static data member got the space into the data segment of memory. Which access with scope resolution operator(i.e. <code>::</code>). But after compilation, there is nothing like scope &amp; namespace. Because, its just name mangling performed by the compiler, everything referred by its absolute or relative address. You can read more about name mangling in C++ <a rel="noreferrer noopener" href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=2&amp;cad=rja&amp;uact=8&amp;ved=2ahUKEwjloqrohPToAhXDILcAHU4eC4kQFjABegQIDhAD&amp;url=https%3A%2F%2Fwww.ibm.com%2Fsupport%2Fknowledgecenter%2Fssw_ibm_i_72%2Frzarg%2Fname_mangling.htm&amp;usg=AOvVaw1JsTeSnCRnH6Cm-FjtqOUq" target="_blank"><span style="color:#9b51e0" class="color">here</span></a>.</li><li>Moreover, static methods go into the text segment and called with the scope resolution operator. Except for <code>this</code> pointer which is not passed in its argument.</li><li>For virtual keyword, the compiler automatically inserts pointer(<code>_vptr</code>) to a virtual table into the object memory representation. So it transforms direct function calling in an indirect call(i.e. dynamic dispatch which I have discussed in <a rel="noreferrer noopener" href="http://www.vishalchovatiya.com/part-1-all-about-virtual-keyword-in-cpp-how-virtual-function-works-internally/" target="_blank"><span style="color:#4c2bd3" class="color">How Does Virtual Function Works Internally?</span></a>). Usually, virtual table created statically per class in the data segment, but it also depends on compiler implementation.</li><li>In a virtual table, 1st entry points to a <code><a rel="noreferrer noopener" href="http://www.cplusplus.com/reference/typeinfo/type_info/" target="_blank">type_info</a></code> object which contains information related to current class &amp; DAG(<a rel="noreferrer noopener" href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=9&amp;cad=rja&amp;uact=8&amp;ved=2ahUKEwjO_sWYgPToAhU4yzgGHfyzAGkQFjAIegQIARAB&amp;url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FDirected_acyclic_graph&amp;usg=AOvVaw1mxaV0fpCPG1RAZSFIC5oJ" target="_blank">Directed Acyclic Graph</a>) of other base classes if it is derived from them.</li><li>I have not mentioned the data type of <code>_vptr</code> because the standard does not mention(even I don't know that).</li></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3>Layout of C++ Object With Inheritance</h3>
<!-- /wp:heading -->

```c++
class X {
    int     x;
    string str;

public:
    X() {}
    virtual ~X() {}

    virtual void printAll() {}
};

class Y : public X {
    int     y;

public:
    Y() {}
    ~Y() {}

    void printAll() {}
};
```

<!-- wp:list -->
<ul><li>Memory layout:</li></ul>
<!-- /wp:list -->

<!-- wp:enlighter/codeblock {"linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">      |                              |          
      |------------------------------| &lt;------ Y class object memory layout
      |          int X::x            |
stack |------------------------------|
  |   |              int string::len |
  |   |string X::str ----------------|
  |   |            char* string::str |         
 \|/  |------------------------------|      |-------|--------------------------|
      |           X::_vptr           |------|       |       type_info Y        |
      |------------------------------|              |--------------------------|
      |          int Y::y            |              |    address of Y::~Y()    |
      |------------------------------|              |--------------------------|
      |               o              |              | address of Y::printAll() |
      |               o              |              |--------------------------|
      |               o              |              
------|------------------------------|--------
      |           X::X()             | 
      |------------------------------|       |   
      |           X::~X()            |       |
      |------------------------------|       | 
      |         X::printAll()        |      \|/ 
      |------------------------------|  text segment
      |           Y::Y()             |
      |------------------------------|
      |           Y::~Y()            |
      |------------------------------|
      |         Y::printAll()        |
      |------------------------------|
      |      string::string()        |
      |------------------------------|
      |      string::~string()       |
      |------------------------------|
      |      string::length()        |
      |------------------------------|
      |               o              |
      |               o              |
      |               o              |
      |                              |</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:list -->
<ul><li>In the inheritance model, a base class &amp; data member classes are a subobject of a derived class. So, a resultant memory map looks like the above diagram.</li><li>Virtual table with all overridden virtual functions and code to assign <code>_vptr</code> with the virtual table is generated in the constructor of the class by the compiler. I have written more on this topic in the <a rel="noreferrer noopener" aria-label="virtual function series (opens in a new tab)" href="http://www.vishalchovatiya.com/part-1-all-about-virtual-keyword-in-cpp-how-virtual-function-works-internally/" target="_blank"><span style="color:#1e4ede" class="color">virtual function series</span></a>.</li></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3>Memory Layout of an Object With Multiple Inheritances &amp; Virtual Function</h3>
<!-- /wp:heading -->

```c++
class X {
public:
    int     x;
    
    virtual ~X() {}
    virtual void printX() {}
};

class Y {
public:
    int     y;
    
    virtual ~Y() {}
    virtual void printY() {}
};

class Z : public X, public Y {
public:
    int     z;
    
    ~Z() {}
    void printX() {}
    void printY() {}
    void printZ() {}
};
```

<!-- wp:list -->
<ul><li>Memory layout: </li></ul>
<!-- /wp:list -->

<!-- wp:enlighter/codeblock {"linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">      |                              |          
      |------------------------------| &lt;------ Z class object memory layout
stack |          int X::x            |         
  |   |------------------------------|                  |--------------------------|      
  |   |          X:: _vptr           |----------------->|       type_info Z        |
  |   |------------------------------|                  |--------------------------|
 \|/  |          int Y::y            |                  |    address of Z::~Z()    |
      |------------------------------|                  |--------------------------|
      |          Y:: _vptr           |------|           |   address of Z::printX() |
      |------------------------------|      |           |--------------------------|
      |          int Z::z            |      |           |--------GUARD_AREA--------|    
      |------------------------------|      |           |--------------------------|
      |              o               |      |---------->|       type_info Z        |
      |              o               |                  |--------------------------|
      |              o               |                  |    address of Z::~Z()    |
      |                              |                  |--------------------------|
------|------------------------------|---------         |   address of Z::printY() |
      |           X::~X()            |       |          |--------------------------|  
      |------------------------------|       |          
      |          X::printX()         |       |        
      |------------------------------|       |         
      |           Y::~Y()            |      \|/        
      |------------------------------|  text segment
      |          Y::printY()         |                
      |------------------------------|                
      |           Z::~Z()            |                
      |------------------------------|                
      |          Z::printX()         |                
      |------------------------------|                
      |          Z::printY()         |                
      |------------------------------|                
      |          Z::printZ()         |                
      |------------------------------|                
      |               o              |                
      |               o              |                
      |                              |                </pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:list -->
<ul><li>In multiple inheritance hierarchy, an exact number of the virtual table pointer(<code>_vptr</code>) created will be N-1, where N represents the number of classes.</li><li>Now, the rest of the things will be easy to understand for you, I guess so.</li><li>If you try to call a method of class <code>Z</code> using any base class pointer, then it will call using the respective virtual table. As an example:</li></ul>
<!-- /wp:list -->

```c++
Y *y_ptr = new Z;
y_ptr->printY(); // OK
y_ptr->printZ(); // Not OK, as virtual table of class Y doesn't have address of printZ() method
```

<!-- wp:list -->
<ul><li>In the above code, <code>y_ptr</code> will point to subobject of class Y within the complete <code>Z</code> object.</li><li>As a result, call to any method for say <code>y_ptr-&gt;printY();</code> using <code>y_ptr</code> will be resolved like:</li></ul>
<!-- /wp:list -->

<!-- wp:enlighter/codeblock {"language":"cpp","linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="cpp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""> ( *y_ptr->_vtbl[ 2 ] )( y_ptr )</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:list -->
<ul><li>You must be wondering why I have passed <code>y_ptr</code> as an argument here. It's because of an implicit <code>this</code> pointer, you can learn about it <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="http://www.vishalchovatiya.com/how-cpp-object-used-internally-in-the-executable/" target="_blank"><span style="color:#2724cf" class="color">here</span></a>.</li></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3>Layout of Object Having Virtual Inheritance</h3>
<!-- /wp:heading -->

```c++
class X { int x; };
class Y : public virtual X { int y; };
class Z : public virtual X { int z; };
class A : public Y, public Z { int a; };
```

<!-- wp:list -->
<ul><li>Memory layout: </li></ul>
<!-- /wp:list -->

<!-- wp:enlighter/codeblock {"linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">                  |                |          
 Y class  ------> |----------------| &lt;------ A class object memory layout
sub-object        |   Y::y         |          
                  |----------------|             |------------------| 
                  |   Y::_vptr_Y   |------|      |    offset of X   | // offset(20) starts from Y 
 Z class  ------> |----------------|      |----> |------------------|     
sub-object        |   Z::z         |             |       .....      |     
                  |----------------|             |------------------|  
                  |   Z::_vptr_Z   |------|       
                  |----------------|      |        
 A sub-object --> |   A::a         |      |      |------------------| 
                  |----------------|      |      |    offset of X   | // offset(12) starts from Z
 X class -------> |   X::x         |      |----> |------------------|          
 shared           |----------------|             |       .....      |           
 sub-object       |                |             |------------------|           </pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:list -->
<ul><li>Memory representation of derived class having one or more virtual base class divides into two regions: <ol><li>an invariant region</li><li>a shared region</li></ol></li><li>Data within the invariant region remains at a fixed offset from the start of the object regardless of subsequent derivations. </li><li>However, shared region contains a virtual base class and it fluctuates with subsequent derivation &amp; order of derivation. I have discussed more on this in <a rel="noreferrer noopener" href="http://www.vishalchovatiya.com/part-2-all-about-virtual-keyword-in-cpp-how-virtual-class-works-internally/" target="_blank"><span style="color:#2724cf" class="color">How Does Virtual Inheritance Works?</span></a>.</li></ul>
<!-- /wp:list -->


[Have Any Suggestions, Query or Wants to Say `Hi`? Take the Pressure Off, You Are Just a Click Away.](http://www.vishalchovatiya.com/contact-2/)🖱️