Memory Layout in C++
Memory Management In OS
We write a computer program in a text file and when we execute, OS allocates a process which performs all the task mentioned in the program.
Our program gets assigned a process and each process is allocated some memory and which is divided into below-mentioned segments:
- Text Segment
- Data Segment
- Stack
- Heap
This topic comes under Process and Process Management in the Operating System.
Hence when we run our C++ program the OS allocates a process that contains a block of memory.
- Text Segment:
Also, know as Code segment, Contains executable instructions.
Usually, Text segment is sharable and hence only a single copy exists as well as its read-only. - Data Segment
Divided into two parts
Initialized Data Segment
Contains Global and static variables that are initialized. Its not a read-only segment and hence the values can be modified.
Uninitialized Data Segment
This is usually called BSS segment.
Data in this segment are initialized by the kernel to 0 before the program starts execution. This comes after the initialized Data segment in memory. - Stack:
Temporary variables are stored in this area. The virtual pointer is also stored here
Stack Frame: A set of values pushed for one function call is called Stack Frame. - Heap:
Here dynamic memory allocation takes place
Memory Layout of objects in C++:
- Simple Object
- Object with virtual and static members
- Object with inheritance
- Object with Multiple inheritances and virtual functions
1. Memory Layout of Simple Object:
class Shape {
float area;
float perimeter;
public:
Shape();
~Shape();float GetArea(float side);
float GetPerimeter(float side);
};
Stack:
1. area
2. perimeter
Text Segment:
1. Shape()
2. ~Shape()
3. GetArea(float side)
4. GetPerimeter(float side)
2. Object with virtual and static members
class Shape {
float area;
float perimeter;
static double PI;
public:
Shape();
virtual ~Shape();virtual float GetArea(float side);
float GetPerimeter(float side);static double GetPI();
};
Stack:
1. area
2. Perimeter
3. _vptr
Data Segment:
1. Static Shape::PI
Text Segment:
1. Shape()
2. ~Shape()
3. GetArea(float side)
4. GetPerimeter(float side)
5. Static Shape::GetPI()
- Here as you can see the static member variable goes into the Data Segment.
- The static function goes into the Same text segment as other function but here this pointer won't be passed.
- In the case of virtual members, a virtual pointer is added to the stack which points to a virtual table which contains:
- type_info — Contains information related to the current class and other classes if it is derived from one.
- Address of virtual function:
- ~Shape()
- GetArea()
3. Object with inheritance
class Shape {
float area;
public:
Shape();
virtual ~Shape();virtual float GetArea(float side);
};class Square : Shape {
float area;
public:
Square();
~Square();float GetArea(float side);
};
Stack:
1. Square::area
2. Shape::_vptr
3. Shape::area
Text Segment:
1. Square()
2. ~Squre()
3. Square::GetArea()
4. Shape()
5. ~Shape()
6. Shape::GetArea()
The virtual table will be created as part of a constructor call to base class Shape and the table will contain the address of virtual functions that are overridden.
Object with Multiple inheritances and virtual functions
class Shape {
float area;
public:
Shape();
virtual ~Shape();virtual float GetArea(float side);
};class Square {
float area;
public:
Square();
~Square();virtual float GetArea(float side);
};class TempShape : public Square, public Shape {
float area;
public:
TempShape();
~TempShape();float GetArea(float side);
};
An object of TempSape class memory layout:
Stack:
1. Shape::area
2. Square::area
3. TempShape::area
4. Shape::_vptr
5. Square::_vptr
Text:
1. TempShape()
2. ~TempShape()
3. Square()
4. ~Square()
5. Shape()
6. ~Shape()
Here if you see the object of TempSpace contains two vptr.
In multiple inheritance the no of vptr created will N-1, where N is the no of class.