The CyberPlus Blog

Our Interface to the Community!

  • Home
  • About

16

Oct

Memory Layout for C Programs in Linux

Posted by Nagesh Rao  Published in C, Linux

Every running program (process) occupies some memory for its code and data. Linux follows a particular methodology for assigning memory addresses to various parts of a program. Linux assigns a “segment” to each of the following, where a segment can be defined as a single memory block of variable size:

  1. TEXT
    This is the code segment and contains only the executable code of the program. In Linux, this is a read-only segment, implying that it’s contents can never be overwritten by the program. Thus, Linux does not support self-modifying code.
  2. DATA
    This segment contains all the data that is required throughout program execution. In C terms, this includes all extern and static variables. This is split into two physical parts:

    1. Initialized Data Segment
      This contains all the extern and static variables of the program that been explicitly initialized in the program
    2. Uninitialized Data Segment (Also called BSS: Block Started by Symbol, a historial and outdated term!)
      This contains all the extern and static variables of the program that not been explicitly initialized in the program, and hence have to be automatically initialized to 0.
  3. STACK
    This segment contains all local variables that are created when control enters a function. Note that these also include function parameters.
  4. HEAP
    This segment is internally kept track via a linked list, and is used by dynamic variables (memory allocated using malloc and calloc). Frequent memory allocations and deallocations result in fragmentation here.

The memory layout of a typical C program is shown below:

Memory Segment

Memory Layout for C Programs in Linux

There is a strong reason for this arrangement. Note these points:

  1. The TEXT segment is loaded from the executable file
  2. The DATA segment is also blindly loaded from the executable file
    These points mean that the first part of the memory is a copy of data from the executable
  3. The BSS segment is NOT stored in the executable!
    This saves space, as the whole block is anyway full of zeros.
  4. The HEAP and the STACK grow towards each other.
    This ensures that both have enough space, and you would not get problems like too much stack space and too little heap space or vice-versa
  5. The Command Line Arguments and the Environment are dumped at the far end of the accessible memory block.

Finally, note that all addresses discussed here are logical addresses, and the actual physical address can be mapped anywhere in memory!

Given below is a C program to illustrate the above concept. We have:

  1. An initialized global variable, called init_global_var
  2. An uninitialized global variable, called global_var
  3. An initialized static variable in global scope, called init_static_var
  4. An uninitialized static variable in global scope, called static_var
  5. An initialized static variable within a function, called init_static_local_var
  6. An uninitialized static variable within a function, called static_local_var
  7. An initialized local variable, called init_local_var
  8. An uninitialized local variable, called local_var
  9. A dynamic variable, with address in dynamic_var
  10. An environment variable, with address in environ
/*
 * memorySegments.c
 *
 * A program to illustrate the logical addressing space within processes
 *
 * (c) 2008 Nagesh Rao, CyberPlus Infotech Pvt. Ltd.
 */

#include <stdio.h>
#include <stdlib.h>

int init_global_var = 10;        /* Initialized global variable */
int global_var;                  /* Uninitialized global variable */
static int init_static_var = 20; /* Initialized static variable in global scope */
static int static_var;           /* Uninitialized static variable in global scope */

int main(int argc, char **argv, char **envp)
{
        static int init_static_local_var = 30;   /* Initialized static local variable */
	static int static_local_var;             /* Uninitialized static local variable */
	int init_local_var = 40;                 /* Initialized local variable */
	int local_var;                           /* Uninitialized local variable */
	char *dynamic_var = (char*)malloc(100);  /* Dynamic variable */

	printf("Address of initialized global variable: %p\n", &init_global_var);
	printf("Address of uninitialized global variable: %p\n", &global_var);
	printf("Address of initialized static variable in global scope: %p\n", &init_static_var);
	printf("Address of uninitialized static variable in global scope: %p\n", &static_var);
	printf("Address of initialized static variable in local scope: %p\n", &init_static_local_var);
	printf("Address of uninitialized static variable in local scope: %p\n", &static_local_var);
	printf("Address of initialized local variable: %p\n", &init_local_var);
	printf("Address of uninitialized local variable: %p\n", &local_var);
	printf("Address of function (code): %p\n", &main);
	printf("Address of dynamic variable: %p\n", dynamic_var);
	printf("Address of environment variable: %p\n", &envp[0]);

	exit(0);
}

The output of the program on my system is as follows:

Address of initialized global variable: 0x80498d4
Address of uninitialized global variable: 0x80498ec
Address of initialized static variable in global scope: 0x80498d8
Address of uninitialized static variable in global scope: 0x80498e8
Address of initialized static variable in local scope: 0x80498dc
Address of uninitialized static variable in local scope: 0x80498e4
Address of initialized local variable: 0xbf94a890
Address of uninitialized local variable: 0xbf94a88c
Address of function (code): 0x80483e4
Address of dynamic variable: 0x86ff008
Address of environment variable: 0xbf94a92c

Tags: Article, C, Linux, memory, process, program

Related Articles

  • C FAQ: How do I compile multiple C programs and link them together? (August 7th, 2014)
  • C FAQ: Size of int and int* on 64-bit machine (July 31st, 2014)
  • C FAQ: What are the sizes of char, short, int and long? (July 22nd, 2014)
  • C FAQ: Is there a difference between variable definition and variable declaration? (July 20th, 2014)
  • A Brief History of C (July 17th, 2014)

No user responded in this post

Subscribe to this post comment rss or