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