C++ object memory distribution of includes byte alignment and virtual function tables

  • 2020-05-10 18:33:20
  • OfStack

1. Memory distribution and virtual function table of C++ object:

C++ object memory distribution and virtual function table note that the object stored is a virtual function table pointer, not a virtual function table, virtual function table has been generated in the compilation stage, the virtual function pointer in different objects of the same class points to the same virtual function table, and the virtual function pointer in different objects points to different virtual function tables.

2. When to conduct dynamic binding:

(1) when each class object is constructed don't need to care about whether there are other classes derived from oneself, also do not need to care about whether he had derived from the other class, as long as according to the process of a series 1: before its own constructor performs the own class (i.e., the constructor's class) the address of the virtual function table is bound to the current object as object is stored in the memory space (1 of 4 bytes). Because the object is constructed from the most basic part of the class (such as A) < -B < -C, A is the most basic class, C is the most derived class) start construction, layer 1 and layer 1 go out to build the middle class (B), and finally build the most derived class (C), so the binding on the final object is naturally the virtual function table of the most derived class.

(2) the destructor is called in the reverse order of the constructor, starting with the destructor of the most derived class. That is, when the destructor of the base class is executed, the destructor of the derived class has already been executed, and the member data in the derived class is considered invalid (including virtual table Pointers in the derived class object). Assuming that the virtual function call in the base class can call the virtual function of the derived class, the virtual function of the derived class will access some data that is already "invalid," causing the same problem as accessing some uninitialized data. Similarly, we can assume that the vtable is constantly changing and unbound during the process of destructing.

Therefore, a call to a virtual function in a base class constructor or destructor is not bound to the implementation of a derived class, because the virtual function table pointer points to the base class's virtual function table when the two functions are executed.

3. Size of C++ :

According to 1, only non-static data members are stored in C++ object, and member functions and static data members are stored in the static data area.

Byte alignment (default) :

1. VC stipulates that the offset of the starting address stored by each member variable relative to the starting address of the structure must be a multiple of the number of bytes occupied by the type of the variable.

2. In order to ensure that the size of the structure is a multiple of the byte boundary number of the structure (that is, the number of bytes occupied by the type occupying the largest space in the structure), VC will automatically fill in the empty bytes as needed after applying for space for the last member variable.

3. If the number of bytes (#pragma pack(n)) is aligned, then

(1) the offset of the starting address stored by each member variable relative to the starting address of the structure must be a multiple of the number of bytes occupied by the type of the variable and the smaller value of n.

(2) the size of the structure is a multiple of the number of bytes occupied by the type occupying the largest space in the structure and the smaller value of n.


class A { 
 double d;
 static int i;
 void f() { std::cout << "A::f" << std::endl; }
}; // 8 byte , only double Data membership 8 The bytes, member functions, and static data members are not in the object, but in the static data area 


class B { 
 int i; //4
 double j;//8
 char k; //
}; // 24 byte , consider byte alignment , 4 + 4 + 8 + 1 + 7 .   The blue 4 It's to satisfy the conditions 1 , the black 7 It's to satisfy the conditions 2 . If you specify 4 Byte aligned, 4 + 8 + 1 + 3


class C { 
 virtual void f() { std::cout << "C::f" << std::endl; }
}; // 4 byte , virtual function table pointer occupation 4 bytes 


class D { 
};// 1 byte , the size of a structure or class without a member variable is 1 Because each of the structures or classes must be guaranteed 1  Each instance is unique in memory 1 The address of the 

Note:

1. If there is a member object, expand the member object directly into the external object, and then size it according to the rule of byte alignment.

2. The memory distribution of virtual inheritance is: virtual class pointer - derived class member data - base class member data. The alignment scheme is: first, take all the members of the derived class as a nested structure form, located at the bottom of the base class data members to ensure their alignment (first address divisible number of bytes), but don't add below bytes to ensure overall integer times the boundary length (because a base class members sharing, the derived class as a whole).

3. If you have an array in an object, you can expand the array into the object and size it in byte alignment.

4. Why byte alignment

The principles of computer composition teach us that this helps speed up a computer's retrieval process, otherwise it would take more instruction cycles. To do this, the compiler, by default, processes the structure (and indeed data variables elsewhere) so that the base data type of 2 (short, etc.) is at an address that is divisible by 2, the base data type of 4 (int, etc.) is at an address that is divisible by 4, and so on. Such as some platform to read every time starts, I address if int type 1 (assuming 32-bit system) as if in my address, then a read cycle can read out the 32 bit, if stored in address starts, you need 2 read cycle, and the results of two readout of high and low together to get the 32 bit data byte.

Note: visual studio 2010 is byte aligned by default for 32-bit gcc by 4 byte maximum


Related articles: