Sunday, September 27, 2015

C language : Memory Layout


Now since we have seen extern,static,local variable and also string. So the next important thing comes is Memory Layout.

Now I myself is studying at the same time and I have lots of doubts . Some get cleared over net and some I just assume to be true or false, until proved otherwise. :)

Most of us knows that C memory layout is basically

Stack, Heap,BSS,Code segment.   But we will here try to see how much we can get . The first thing I will be doing is to mention the various link i have gone through and after that what I understood from these.


http://www.geeksforgeeks.org/memory-layout-of-c-program/
http://cs-fundamentals.com/c-programming/memory-layout-of-c-program-code-data-segments.php
https://www.cs.cmu.edu/~guna/15-123S11/Lectures/Lecture06.pdf
http://www.tenouk.com/ModuleW.html


Now simply put,

Every machine which runs code has Opearting System, RAM , and then our C programs.

Taking GCC into perspective,

The stages of writing and running a program involves.

Using example of below program

#include<stdio.h>

#define CHETAN 12

int main()
{
 printf("%d",CHETAN);
}

1) the best command I got over net to generate all types of file during various stage is

> gcc -o memory memory.c  --save-temps

This will generate

1)  Preprocessor  Stage  :  memory.C  to memory.I  file  Preprocessed code is generated
2)  Compiler Stage   :  memory.I file to memory.S  file   Assemble Code is generated
3)  Assembler Stage  :  memory.S file to memory.O file  Object Code is generated
4)  Linker Stage  :  memory.O file to ELF file                  Executable Code is generated.


Now interested people can workout and see different types of files. All files except ELF and object can be opened with any text editor.

To see Object file code , you can use

> objdump -d memory.o


So we have seen the stages and various code file generated . Now what happens when you run the executable.

The LOADER loads the program into RAM/ primary memory, which creates PROCESS ADDRESS SPACE, since every program we run is a process.


Now every process/ C program can have below types of  variables.

initialized global variable : DATA
uninitialized global variable : BSS
initialized static global variable :  DATA
uninitialized static global variable:    BSS
static local variable ( it should be always initialized):  DATA
static local variable ( in case it is uninitialized):             BSS

local variables:  STACK
malloc space:    HEAP

string literal : ( like char *p="asasasas")  :  READ ONLY DATA    
constant    : READ ONLY DATA


Note  the pointer which points to MALLOC space , there storage location will depend on where that pointer is define.


And finally the object file code which was generated :   TEXT

In case of ELF file, the various section are

ELF file section

.bss        BSS
.text       TEXT
.rodata   READ ONLY DATA

the other gcc command which can be used

> readelf -a memory.o


So this was about ELF section,  STILL I am not sure where local variables and malloc gets stored.


Now about PROCESS ADDRESS SPACE.

It has following sections.

Starting from LOWER ADRESS OF MEMORY.

TEXT : This portion of a process contains the instruction code.  Some OS can share this section between two process running the same code. it is READ ONLY SECTION

DATA segment :  It has  DATA as defined above. Each process has its own set, no SHARING.
 IT is further divided into two parts .

            READ ONLY : global constants , string literals.   char *s="Hello";
            READ WRITE : global and static variables which are not constant. Also  char s[]="hello";

Now if you remember previous post about string, you know the difference between char*s and char s[].

BSS segment : It has BSS as defined above. NO SHARING.

HEAP segment : HEAP.

STACK segement : STACK.


One more thing,  I was wondering where does constant uninitialized variables are stored, On further searching on net I find out that it depends on your compiler.

So  all constant can be saved in text section.  or depending on whether they are global or local and initialized or uninitialized , they can also be stored in thier respective section , i.e BSS,DATA,STACK  since each of these section can have write protected region in them.




So now we know  the stages of C program and how it is stored in RAM.  Further we will see some code and try to find out memory of each section.

we can use SIZE command in ubuntu to check for memory size.

We will be using below program and then add more variables.

int main()
{
}


Now with this program , when I run size I get

text      data   bss   dec     hex    // there is no stack or heap section shown.  The values were
1033    276    4      1313   521

Leave the text part,  I am not sure why   data and bss  has some values even though we have not defined any type of variables.

Lets assume that to be some kind of overhead, in lieu of better explanation.

Now we add a local variable

int main()
{

int a;
}

Now i have  added some local variable, first not assigned any value  there was no change , then when i assigned them value  size of  dec and hex got changes.

You can check more from your side.

Now adding one global int variable, uninitialized   bss size got increased by 4.

Adding uninitialized   static variables,  bss size increased by 4.

Initializing those variables, make data size increase by 4, and bss gets decreased by 4.

Having extern int a;  doesn't increase size since no memory was saved, extern simply tell compiler that this variable is saved somewhere else.



If suppose for  below program the size is like

int main()
{

int a;
}

data   bss
20       4

then what will be size for below program


int main()
{

int a;

int *p=(int *)malloc(sizeof(int)*3);

scanf("%d",&a);

}

it will be

data   bss
28       4

the increase of size of  data is nothing to do with  int *p.....but it seems every function call we made,

that function pointer gets saved in data ...since we have malloc()  and scanf()  size increased by 4*2.


if we add a printf , data size will increase further by 4 bytes.

It seems local function call doesn't increase size , even in local function we are doing malloc.

but if in local function we define static variable, that is stored in DATA segment.



No comments:

Post a Comment