Memory layout of C program in linux


Advertisements

Share



Learn memory layout of C program such as text segment, heap segment, stack segment, command line arguments in linux c with examples.

Memory layout of a C program

    Let us understand the memory layout of running c program.
Text Segment Text Segment is also named as text and it contains executable instructions. This is the lower address occupied by the program in memory. Usually, the text segment is sharable so that only a single copy needs to be in memory for frequently executed programs, such as text editors, the C compiler, the shells, and so on. Also, the text segment is often read-only, to prevent a program from accidentally modifying its instructions.
Data Segment Initialized Data Segment is also named as data. A data segment is a portion of virtual address space of a program, which contains the global variables and static variables that are initialized by the programmer. static int i = 10 will be stored in data segment and global int i = 10 will also be stored in data segment.
BSS segment Uninitialized Data Segment is also named as bss. uninitialized data starts at the end of the data segment and contains all global variables and static variables that do not have explicit initialization in source code.
For instance a variable declared static int i; would be contained in the BSS segment.
Heap Heap is the segment where dynamic memory allocation usually takes place.
The heap area begins at the end of the BSS segment and grows to larger addresses from there. The Heap area is managed by malloc, realloc, and free, which may use the brk and sbrk system calls to adjust its size. The Heap area is shared by all shared libraries and dynamically loaded modules in a process.
StackStack is where automatic and temporary variables are stored, along with information that is saved each time a function is called. Each time a function is called, the address of where to return to and certain information about the caller’s environment, such as some of the machine registers, are saved on the stack. The newly called function then allocates room on the stack for its automatic and temporary variables. This is how recursive functions in C can work. Each time a recursive function calls itself, a new stack frame is used, so one set of variables doesn’t interfere with the variables from another instance of the function.
A stack pointer register tracks the top of the stack; it is adjusted each time a value is pushed onto the stack. The set of values pushed for one function call is termed a stack frame; A stack frame consists at minimum of a return address.
The difference between program counter and stack pointer is that the program counter is a register which holds the address of next instruction when the current instruction is under execution while stack pointer is a pointer which points to the top element of the stack.
Command Line arguments This is the highest address occupied by the program in memory.

C program to demonstrate memory layout

Let's demonstrate the memory layout of a C program using few example programs. To begin with, let's write a simple c program to add two integers.


#include "stdio.h"

int result1;

int main()
{
	int p1 = 10,p2 = 20;
	result1 = add(p1,p2);
	printf("The result is %d\n",result1);
	return 0;
}

int add(int a,int b)
{
	return a+b;
}
Program output:
===============
# ./a.out
The result is 30
//size command output
# size ./a.out
   text    data     bss     dec     hex filename
    830     292       8    1130     46a ./a.out

In the above program we have one global variable result1 declared to store addition result of two integers p1 and p2. Now declare another global variable result2 as shown in the program below.


#include "stdio.h"

int result1;
int result2;

int main()
{
	int p1 = 10,p2 = 20;
	result1 = add(p1,p2);
	printf("The result is %d\n",result1);
	return 0;
}

int add(int a,int b)
{
	return a+b;
}
Program output:
===============
# ./a.out
The result is 30
//size command output
# size ./a.out
   text    data     bss     dec     hex filename
    830     292      12    1134     46e ./a.out

Execute size command to observe the memory allocations as part of bss segment, text segment, text segment as shown above. Things to notice here is that the text and data segments have not changed. But as the variable we declared is uninitialized one the bss segment has changed from 8 to 12 bytes. Also the total bytes now is 830 + 292 + 12 which is 1134bytes which is in hexadecimal 46e.

Now initialize the result2 variable to 30 and the modified program should be as below.


#include "stdio.h"

int result1;
int result2 = 30;

int main()
{
	int p1 = 10,p2 = 20;
	result1 = add(p1,p2);
	printf("The result is %d\n",result1);
	return 0;
}

int add(int a,int b)
{
	return a+b;
}
Program output:
===============
# ./a.out
The result is 30
//size command output
# size ./a.out
   text    data     bss     dec     hex filename
    830     296       8    1134     46e ./a.out

Execute size command to observe the memory allocations as part of bss segment, text segment, text segment as shown above. Things to notice here is that the text and data segments have not changed. But as the variable we declared is uninitialized one the bss segment has changed from 8 to 12 bytes. Also the total bytes now is 830 + 292 + 12 which is 1134bytes which is in hexadecimal 46e.

Now modify the program as shown below and call the function add one more time. Also the total bytes now is 830 + 296 + 8 which is 1134 bytes which is in hexadecimal 46e.


#include "stdio.h"

int result1;
int result2 = 30;

int main()
{
	int p1 = 10,p2 = 20;
	result1 = add(p1,p2);
	printf("The result1 is %d\n",result1);
	result2 = add(p1,p2);
	printf("The result2 is %d\n",result2);
	return 0;
}

int add(int a,int b)
{
	return a+b;
}
Program output:
===============
# ./a.out
The result1 is 30
The result2 is 30

//size command output
# size ./a.out
   text    data     bss     dec     hex filename
    894     296       8    1198     4ae ./a.out

Execute size command to observe the memory allocations as part of bss segment, text segment, text segment as shown above. Here to notice is that the text and bss segments have not changed. But as the variable we declared result2 is initialized one the data segment has changed from 292 to 296 bytes. Also the total bytes now is 830 + 296 + 8 which is 1134bytes which is in hexadecimal 46e.

Exercises, Solutions

Medium
Medium
Low
High
High
Medium
High
Medium
Low
Medium

Want to contribute a new article? Write and upload your article information .
Share

 Articles

 C Programming

 Linux Software

 Search Code Snippets

 Popular C search examples

 Popular C search MCQs

Glass Elite Apple iPhone 11 Pro (Case Friendly)

 Test your skills:online tests

 C Programming

 Python Programming

 Linux Software

 Quantitative Aptitude

 Embedded System Software