Memory and Program

About program’s interaction with memory. What is a memory map of a process and more…

mallard_memory

If you are a programmer, I believe it is a good idea to understand how the program you write would interact with the computer memory. Writing memory efficient programs is of prime importance if you are working on embedded systems with limited memory.

Without further ado, as the meme (actual advice mallard) goes , let’s start decoding. This blog assumes you know basics of programming. You may have heard of stack overflow , memory corruption , null de-reference etc. Getting a view of memory, serves as a tool to address these issues.


Program and process

The terms program and process are used interchangeably. Program refers to the code we write – uncompiled and also compiled version of code with static data in a file. The program stored on the disk contains the compiled code (called the text) as well as initialized data (for example, initialized global integers, strings, and string constants).

Process refers to the executing context of code / ready to be executed code, essentially a program with “execution context”.

Execution context refers to the processor state – program counter and the state of the registers and also the memory map of the given process – that identifies the various regions of the memory allocated to the process.


Memory Map of a process

The memory map of a process identifies the various regions of the memory allocated for execution of the program – “process”. They are categorized by the purpose of usage and the type of data / section of code they hold.

2memory

Fig [1]. Memory Map

STACK

Stack is important during execution of the compiled code. It holds the return address , local variables , temporary data and any saved registers. It is volatile and  changes every time we enter or exit a function or code block during execution.

A given amount of stack is allocated per program. There is a limited size up-to which it can grow. If we exceed the amount of stack memory allocated while running the program – we hit the well known “Stack overflow” issue.

So, managing the allocation of memory for the variables used in code, specially during recursive calls would be a good idea. Check this post on recursion and stack to understand better.

Heap

Any calls to dynamic memory allocation operations such as malloc() or new(), are allocated from this region of the memory. It is a good programming practice to follow this : When a memory is allocated using malloc() (C) /new() (C++), corresponding free()/delete() must be called. Else, this memory may be lost for good – ahem “memory leaks“. In Java , the garbage collector does a automatic delete for you.

Example :

//Dynamic allocation of array
In C and C++, we have to release memory allocated via dynamic memory allocation.
C program:
arr = (int*) malloc(size*(sizeof(int));
if(NULL != arr)
{
free(arr);
}
C++ program:
arr = new int[size];
delete[] arr; //do not access arr after this
Java :
Garbage collector does the delete for you.

Scenario 01.
{
//..
int[] arr = new int[size];
//use array here
arr = null; // dereference it - Garbage collector shall delete.

// execution continue with no use of arr.
//...
//...
//...
} // code block ends at a much later time

or

Scenario 02. 
if (checkInput){
int[] arr = new int[size];
//use arr here 
//code block ends next
} // arr dereferenced here
//Garbage collector shall delete later

Data and BSS (Block start by Symbol)

Data section contains initialized static and global data. BSS contains uninitialized static data – global uninitialized strings, structures etc. The size of the region is contained within the program.

Text

This contains the compiled program or the machine instructions.


Sample Program and Memory map

#include 
#define NUM_ENTRIES 10  // MACRO preprocessor directive
static const int num_st_entries = 5; // DATA section

int main()
{
int* dynamic_data_ptr ;
dynamic_data_ptr = (int*) malloc(sizeof(int)); // HEAP MEMORY
while(NULL != dynamic_data_ptr) 
{
//use the dynamic_data_ptr 
free(dynamic_data_ptr); // explicitly release memory after use.
}
show_stack_operation(); //function call
}  // end of main

void show_stack_operation()
{
static num_func_calls; // BSS
int st_data[NUM_ENTRIES ]; //STACK
int arr[num_st_entries]; // STACK

for (int i=0; i< NUM_ENTRIES;i++)
{
st_data [i] = i; //STACK
} 
num_func_calls++;  //Note : num_func_calls shall persist in memory even 
                     //after we exit the function 
printf("This is %d th call to this function \n", num_func_calls);
}   //array st_data[] used here shall be discarded from 
    // memory once we exit the function

 I will stop at this introductory view for now. I plan to write few more detailed blog entries about each of these sections and most common issues encountered while using them. Continue reading and decoding until then.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: