A brief description of C + + object Model memory distribution of C + + objects

Source: Internet
Author: User

in C + +, there are two kinds of member variables: static and non-static, with three member functions: static, non-static, and virtual. So how do they affect the distribution of C + + objects in memory? When there is inheritance, what about its memory distribution?

The following is a very simple class, through the gradual addition of various members to each analysis of the above two member variables and three member functions of the object of the class of the memory distribution effect.

Note: The test results for the following code are based on the g++ 4.8.2 of the Ubuntu 14.04 64-bit system and may run different results on other systems or with other compilers.

1. Memory distribution of objects of classes containing static member variables and member functions
the definition of class persion is as follows:
Class person{public    : Person        (): mId (0), MAge {{}        void print ()        {            cout << "ID:" << mid                 << ", Age:" << mAge << Endl;        }    Private:        int mId;        

The person class contains two member variables of the non-static int type, one constructor and one non-static member function. To figure out the memory distribution of objects of this class, do some of the following for objects of that class:
int main () {person    p1;    cout << "sizeof (p1) = =" << sizeof (p1) << Endl;    int *p = (int*) &p1;    cout << "p.id = =" << *p << ", Address:"  << P << Endl;    ++p;    cout << "P.age = =" << *p << ", Address:" << p << Endl;    cout << Endl;        person P2;    cout << "sizeof (p2) = =" << sizeof (p1) << Endl;    p = (int*) &p2;    cout << "p.id = =" << *p << ", Address:" << p << Endl;    ++p;    cout << "P.age = =" << *p << ", Address:" << p << Endl;    

the results of the operation are as follows:


The memory used by objects that can see the class is 8 bytes, and a normal int* pointer can traverse the value of a non-static member variable within the output object, and the address of the same non-static member variable in two objects varies.

From this , it can be concluded that in C + +, non-static member variables are placed in each class object, non-static member functions are placed outside the object of the class, and non-static member variables are stored in memory in the order that they are declared within the class. The memory distribution for the person object is as follows:



2. Memory distribution of objects of classes containing static and non-static member variables and member functions

Add a static member variable and a static member function to the person class, as follows:
Class person{public     : Person         (): mId (0), MAge {++scount;}         ~person () {--scount;}         void print ()         {             cout << "ID:" << mId                  << ", Age:" << mAge << Endl;         }         static int Personcount ()         {             return scount;         }     Private:         static int scount;         int mId;         

The test code is the same as the code in section 1th. The result of the operation is the same as in section 1th.

from this, it can be concluded that static member variables are stored outside the object of the class, and static member functions are placed outside the object of the class.

Its memory distribution is as follows:


3.Memory distribution of objects of classes that join the virtual member function

Add a virtual function to the person class and modify the previous print function to function as follows:
Class person{public    : Person        (): mId (0), MAge {++scount;}        static int Personcount ()        {            return scount;        }        virtual void print ()        {            cout << "ID:" << mId                 << ", Age:" << mAge << Endl;        virtual void Job ()        {            cout << "person" << Endl;        }        Virtual ~person ()        {            --scount;            cout << "~person" << Endl;        }    Protected:        static int scount;        int mId;        int mAge;};

in order to see the memory distribution of the object of the class, perform the following operation code on the object of the class, as follows:
int main () {person person    ;    cout << sizeof (person) << Endl;    int *p = (int*) &person;    for (int i = 0; i < sizeof (person)/sizeof (int); ++i, ++p)    {        cout << *p << Endl;    }    

the results of the operation are as follows:


As you can see, after adding the virtual member function, the object size of the class is 16 bytes, which increases by 8. Traversing the memory of the object through the int* pointer, you can see that the last two rows show the value of the member data.

virtual Functions in C + + are implemented by virtual function tables (VTBL), each of which produces a pointer to each virtual function, placed in a table, which is the virtual function table. Each class object is placed with a pointer (vptr) that points to the virtual function table of the class. The vptr settings and resets are automatically completed by the constructors, destructors, and copy assignment operators for each class.

Because my system is a 64-bit system, a pointer size of 8 bytes, so can be launched, in my environment, the placement of the class object vptr placed in the memory of the object of the first. The memory distribution map is as follows:
Note: The order of the virtual function is defined in the order of the virtual function definition, but it also contains some other fields that I do not understand, and the contents of the virtual function table are explained in detail in the next section.


4, the contents of virtual function table (VTBL) andfunction pointer hold order
in the 3rd section, we know where the pointer to the virtual function table (VPTR) is positioned in the class, and the data in the function table is a function pointer, so you can use this to traverse the virtual function table and test the contents of the virtual function table.

The test code is as follows:
typedef void (*FUNCPTR) (); int main () {person person    ;    int **vtbl = (int**) * (int**) &person;    for (int i = 0; i < 3 && *vtbl = NULL; ++i)    {        funcptr func = (funcptr) *vtbl;        Func ();        ++vtbl;    }    while (*VTBL)    {        cout << "*vtbl = =" << *vtbl << Endl;        ++vtbl;    }    return 0;}

Code Explanation:
Because the virtual function table is located at the first position of the object, and the virtual function table holds a pointer to the function, if the virtual function table is treated as an array, it requires a double pointer to point to the array. We can get the address of the object of the person class in the following way and convert it to the int** pointer:
Person Person;int **p = (int**) &person;

The address of the virtual function table is then obtained by the following expression:
int **vtbl = (int**) *p;

then, the address of the function in the virtual function table is obtained by the following statement, and the function is called.
funcptr func = (funcptr) *vtbl;func ();

Finally, the next address of the function table can be obtained through ++VTBL, thus traversing the entire virtual function table.

the results of the operation are as follows:


As you can see, traversing the virtual function table and calling the function from the function address in the virtual function table, it calls the print function, calls the job function, and finally calls the destructor. The order in which the functions are called is consistent with the order in which the virtual functions in the person class are defined, and their memory distribution is consistent with the object memory distribution graph in section 3rd. From the code and running results, you can see that the virtual function table ends with a null flag table. But the virtual function table also contains other data, I have not clear its role.

5. Inheritance effect on memory distribution of objects of class
This article does not intend to describe in detail the effect of inheritance on the memory distribution of objects, nor does it introduce the implementation mechanism of virtual functions. Here is the main one after I test the approximate object memory model, because the code is more, do not post. Assume that all classes have non-static member variables and member functions, static member variables and member functions, and virtual functions.
1) Single inheritance (only one parent class)
Class inherits from: Class Derived:public Base

The memory layout of an object of the derived class is: a virtual function table pointer, a non-static member variable of the base class, and a non-static member variable of the derived class.

2) Multiple inheritance (multiple parent classes)
The inheritance of classes is as follows: Class Derived:public Base1, public Base2

The memory layout of the objects of the derived class consists of the base class Base1 child objects and the base class Base2 child objects and the non-static member variables of the derived class. A base class sub-object includes its virtual function table pointer and its non-static member variable.

3) Duplicate inheritance (the parent class in the inherited multiple parent class has the same superclass )
The inheritance relationship of the class is as follows:
class Base1:public Base
class Base2:public Base
class Derived:public Base1, public Base2

The memory layout of an object of the derived class is similar to multiple inheritance, but you can see that the child object of base class base has a copy in memory of the object of the derived class. When you use the related members of base class base directly in derived, you will get ambiguous and use multiple virtual inheritance to eliminate them.

4) multiple virtual inheritance (using virtual inheritance, in order to ensure that the memory layout of the inherited stepfather class will only exist one copy )
The inheritance relationship of the class is as follows:
Class Base1:virtual Public Base
Class Base2:virtual Public Base
Class Derived:public Base1, public Base2

The memory layout of an object of the derived class is similar to the memory distribution of an object that repeats an inherited class, but a child object of base class base does not have a copy, and only child objects in the object's memory exist in one base class. But its non-static member variable is placed at the end of the object.

A brief description of C + + object Model memory distribution of C + + objects

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.