October 28, 2011

C++ - Memory Segmentation in C++

Introduction - Memory Segments

In the previous article, we saw about the pointer and reference variables in the context of stack memory. There are 3 more important memories that every c++ programmer should be aware of it. Below is the four important memory segmentation:
  1. Stack Memory Segments
  2. Heap Memory Segments
  3. Code Segmentation
  4. Data Segmentation
In this article, we will have a look at these memory segments with a simple example. The example is just for understanding the purpose and it does nothing actually excepting printing something.

Memory Segments - An example

The complete example is shown below:

// CPPTST.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <conio.h>
//MemSeg01: Declare a Global Variable
int x = 10;

//MemSeg02: Store address of the Global variable in a Global Pointer
int* px = &x;

//MemSeg03:  Function definition. Takes a number and prints it
void PrintNo(int x)
 int y;
 y = x;
 printf("The given number is %d", x);

int _tmain(int argc, _TCHAR* argv[])
 //MemSeg04: Declare a loval variable and declare a pointer and store the address of local variable
 int m = 12;
 int* pm = &m;

 //MemSeg05: Local pointer storing the Global Address
 int* pgx = &x;

 //MemSeg06: Local pointer storing the heap address and assigning a value to the heap
 int *pInt = new int;
 *pInt = 22;

 //MemSeg07: Local pointer to a function that returns void and takes int
 void (*pFun)(int);

 //MemSeg08: Pointer storing the base address of the function
 pFun = &PrintNo;

 //MemSeg09: Calling the function through function pointer

 return 0;

Let us explore the example in terms of the memory segmentations.

Code Memory Segment

Well. The code is displayed above. What will you do with it? The first thing is compiling it and then linking the code. Let use assume that the above code is placed in the MyProgram.CPP file. When you compile, the compiler will translate this human readable language into something that called as object code. If there are 20 such files, the job of the compiler is to generate twenty different object files and prompt any errors that do not comply to the C++ syntax. Then the linker will go through all 20-object files to form an executable that is the .exe file.

What happens when you double click the exe name? The exe is considered as a process by the operating system and once the process is committed, the M/c code (exe) is loaded into the memory and processor will access these machine instructions to perform specified action. This memory is called Code Segment. In out example, the translated code goes as exe, and when the exe is executed, the instructions are loaded into the memory called code segment.

Let us take the first statement in the Program entry:

//MemSeg04: Declare a local variable and declare a pointer and store the address of local variable
int m = 12;

The above code will be translated and packed in the exe as a machine-readable language. In the VS2005 IDE, I kept a breakpoint on the above-shown statement and once the breakpoint is hit, using the context menu I asked for show Assembly code. The Assembly revealed is shown below:

The address marked in Red box shows it stores the assembly command MOV (It may be mapped to number and then in terms of zeros and ones that is low and high voltage. We no need to go that much deep into the electronics of it). The Address in the Red box is actually allocated in the Code Segment. A pointer can store this address also.

Data Memory Segment

As the name implies it is the segment for application data. Do you heard your senior asking multiple questions when you declare a global variable? He asks, because the global variables go and sit in the data segment of the memory. So what? If it sits there, it lives until the program dies and there is no ways to say get lost. Think about a big project and 1000 of people worked on it (Even in maintenance) for last 10 to 20 years declared plenty of global variables even when it is avoidable by alternate techniques. When the program loads (in Code segment) it needs to allocate space for all those variables and allocated space is never cleared until the program exits. That is why we call these global variables and constants are application data. The memories associated to these global are known as data segment memory and it will get cleared when the program is removed.

In our example the following two statements are occupying the memory in the data segment.

//MemSeg01: Declare a Global Variable
int x = 10;
//MemSeg02: Store address of the Global variable in a Global Pointer
int* px = &x;

Note that the pointer px is holdling the address of some data segment memory allocated to variable integer x. Also, the space required for holding that address also allocated in the data segment. Here, the value in the px, x can be changed. But, the space allocated for it cannot be washed out.

Heap Memory Segment

Allocating and clearing the memory in the memory segment for Stack, Code and data is taken care by the system. But, heap memory is given in the hands of C++ programmer. They can create byes of memory as well as clear it whenever they want.  So the programmer determines the lifetime of the memory allocated. Consider the statement below taken from the example:

//MemSeg06: Local pointer storing the heap address and assigning a value to the heap
int *pInt = new int;
*pInt = 22;

In the above statements, space required to store an integer value is allocated in the heap. The allocated address is stored in the variable pInt. The variable pInt is inside the main function and so the space for variable pInt is allocated in the stack holding address in the heap (Enough to store an integer).  So when we go out of the function all the stack memory associated to it is cleared. But, the allocated heap becomes un attended or blocked stating in use. Because system will not clear it and programmer should do that. To clear that heap, before you lose the address in the stack for pInt, you should use the statement delete pInt.

What happens if the above two statements are next to the comment MemSeg01 that is not inside any of the function? Well. Heap memory is stored in data segment variable pInt.

Stack Memory Segment

It is the memory segment where almost everybody declares and uses the variables. When you declare a variable inside the function that goes to the stack segment of the memory. All the stack segments wiped out once you go out of the function and when you come inside the some other function a new stack segment for that function is created. So this is a less costly segment as it lives till corresponding function returns back to the caller.
Let us assume Program main calls the function A. Here first the Stack Segment for Main is created, then when you are inside the function A, main programs stack segment becomes un-accessible and at the same time stack segment for Function A is created. When the function A return the control to main program, stack segment for A is cleared and stack segment for program main (Still lives, it became temporarily un-accessible) becomes available. You can refer my previous post for detailed example about stack segment.

In our example the below two statements in the main is created in stack segment:

//MemSeg04: Declare a loval variable and declare a pointer and store the address of local variable
int m = 12;
int* pm = &m;

Before we close

Below is the Illustration of memory segment and variable involved in our sample.

We know that a pointer can hold an address. In our example,

Pm – is holding the address of memory in stack segment
Pgx – is holding the address of the memory in the data segment
Pint – is holding the address of the memory in the heap segment
PFun – is holding the address of the memory (Starting address or base address of the void PrintNo(int x) ) in the code segment.


That is function pointer, I will write about it later. There is a nice movie in HBO, I will spend sometime there.

No comments:

Post a Comment

Leave your comment(s) here.

Like this site? Tell it to your Friend :)