Session 06
Preprocessor Directories and
 Memory Allocation
 1
 Session Objectives
• To learn about Preprocessor directives
• To understand concept of File Inclusion
• To understand concept of Conditional Compilation
• To learn about of Dynamic Memory Allocation
• To understand concept of malloc(), calloc(), realloc(),
 free()
 2
 Session Topics
• Library functions and header files
• #defined and #include directives
• Macro substitution
• Conditional compilation directives
• Dynamic memory allocation
• malloc(), calloc(), realloc(), free()
 3
 The Preprocessor
A preprocessor is a facility provided for writing portable
programs,easier program modifications and easier debugging.
A preprocessor processes the source code program before it
passes through the compiler.
The preprocessor is a part of the compiler.It is implemented as
an integral part of a Standard C Compiler.
It is a separate program which transforms C source code
containing preprocessor directives into source code with the
directives removed.
It works on a line-by-line basis, so the end of a line means
something special to it.
 4
 Features of Preprocessors
 File Inclusions
 -- #include directive
• Substitution facilities
 -- Manifests
 -- Macros
 Conditional Compilation
 -- #if
 -- #else
 5
 Directives
• Directives are preprocessor control lines that
 control the preprocessor facilities.
• They start with the symbol ‘#’.
• The directives can be placed anywhere in a
 program but are most often placed at the
 beginning of a program, before main().
 6
 File Inclusion Directives
• The #include is the directive for file inclusion.
• This directive causes one file to be included in another.
• There are two ways of writing the #include directive.
• They are :
 #include “file_name”
 #include <file_name>
 7
 #include
#include “file_name”
• This command would search the directory that contains the
 source file.
• If the search fails in the home directory it searches the
 implementation defined locations.
• This command would look for the file in the current
 directory as well as the specified list of directories as
 mentioned in the include search path that might have been
 set up.
 8
 #include
 #include <file_name>
• This command would search only in the
 implementation defined locations
• This command would look for the file in the
 specified list of directories only
 9
 Substitution Facilities
 There are two types of Substitution Facilities
 available.They are:
• Manifests
 Manifest is defined as #define NAME value
 Example: #define MAX 10
• Macros
 Macro is defined as
 #define NAME(arg) expression
 Example:#define SQR(x) ((x) * (x))
 10
 Macro
A macro is a simple function having its own
syntax using #define,
It is defined with one or a few statements.
It is invoked in the same way as function call.
 11
 #define
 Macro template
 Macro definition
 #define VALUE 25
 main()
 { Macro expansion
 int j;
 for(j=1;j<=VALUE;j++)
 printf(“%d”,i);
 }
NOTE:In a macro call the preprocessor replaces the
macro template with its macro expansion.
 12
 Differences:Macros & Functions
 Macros Functions
• They are expanded at pre- • They are expanded at compile
 compile time. time.
• They are expanded by the • They are parsed by the
 preprocessor. compiler.
• They do not follow any rules.It
 • They follow all the rules
 is merely a replacement.
 enforced on functions.
• Expressions passed as
 arguments can be evaluated • Expressions passed as
 more than once. arguments are evaluated only
• Code used by macros cannot be once.
 used for debugging. • Code used by functions can be
 used for debugging.
 13
 Conditional Compilation
 A section of source code may be compiled
 conditionally using the conditional compilation
 facilities.
 The directives used for this purpose are:
 -- #if
 -- #elseif
 -- #else
 -- #endif
• These directives behave much like the if-else or if-
 else-if control structure.
 14
 #undef, #ifdef, #ifndef, #endif
On some occasions, it may be desirable to cause a
defined name to become undefined using #undef
directive.
#undef would cause the definition to be removed
from the system.
All #ifdef statements would evaluate to false.
We can have the compiler skip over certain part of
a source code by inserting commands like #ifdef
and #endif.
 15
Pseudo Code
 16
 #if, #else,# elif
The #if directive can be used to test whether an expression evaluates to
a nonzero value or not.
If the result of the expression is nonzero, then the subsequent lines up
to a #else, #elif or #endif are compiled.
main()
{
 #if VALUE <=5
 statement 1;
 statement 2;
 #else
 statement 3;
 statement 4;
 #endif
}
 17
 Pseudo Code
main()
{
 #if VALUE == 5
 statement 1;
 #elif
 statement 2;
 #elif
 statement 3;
 #else
 statement 4;
 #endif
}
 18
 Stringizing Operator ‘#’
The macro parameters in the strings that appear in the
macro definitions are not recognized.
To substitute a macro argument in a string constant, a
special notation ‘#’ in the macro body.
When the ‘#’ character precedes a parameter in the macro
body, a string constant is replaced for both # and the
parameter.
The notation ‘#’ is known as the Stringizing Operator.
 19
 An Example: ‘#’
#define STRING(x,y) #x”developed by”#y
main()
{
 char s[]=STRING(PROGRAM,ARUN);
 printf(“%s\n”,s);
}
Output:
PROGRAM developed by ARUN
 20
 Token Pasting Operator:’##’
A notation ‘##’ used in a macro definition
concatenates the two tokens on either side of the
symbol ## into one token.
If the concatenation results in an invalid token, the
result is undefined.
The notation ## is called as Token Pasting
Operator.
 21
 An Example: ‘##’
#define DECIMAL(x) 3.##x
main()
{
 printf(“%f\n”,DECIMAL(14));
}
Output:
3.140000
 22
 Advantages of Preprocessors
A preprocessor improves the readability of
programs.
If facilitates easier modifications.
It helps in writing portable programs.
It enables easier debugging.
It enables testing a part of a program.
It helps in developing generalized program.
 23
 Variable Length Argument List
 When a programmer does not know how many arguments
 are there in a function, then this crisis can be solved using
 the concept of Variable Length Argument lists.
 The printf() function works on this concept.
 The function header could look like this
 int average(int x,…)
It tells the compiler to
 accept variable Ellipsis
number of arguments.
 24
 Macros used in VLAL
• va_start()  Initializes the list
• va_arg()  Returns the next argument in the list
• va_end()  Cleans up the argument list
• va_list()  Variable should be declared of type
 va_list.
 Example: va_list a_list;
 25
 An Example:VLAL
#include<stdio.h>
#include<stdarg.h>
double average(int num,…) {
 va_list arguments;
 double sum=0;int x;
 va_start(arguments,num);
 for(x=0;x<num;x++) {
 sum = sum + va_arg(arguments,double); }
 va_end(arguments);
 return sum/num; }
void main() {
printf(“%f\n”,average(3,12.2,22.3,4.5));
printf(“%f\n”,average(5,3.3,2.2,1.1,5.5,3.3)); }
 26
 Dynamic Memory Allocation
Dynamic memory allocation is the process of
allocating memory space during rum time.
It is a unique feature in C.
It allows us to create variables of various data
types and structures of any size and length
whenever we require during execution time.
In situations, where there is an unpredictable
storage requirement, this technique is very useful.
 27
 Static Memory Allocation
• The memory space allocated during compilation
 time is called as Static Memory Allocation.
• The allocated memory space cannot be expanded
 to accommodate more data or cannot be reduced
 to accommodate less data.
• The memory space allocated is fixed and we
 cannot alter the size of the allocated space any
 time during execution.
• Example: int a[10];
 28
Memory Map of a C Program
 Automatic
 Stack
 Variables
 .
Free Memory Heap Memory
 .
Global/Static
 Variables RAM
 C Program
 BIOS ROM
 29
 malloc()
The function allocates and reserves a block of
memory,specified in bytes and returns a pointer to
the first byte of allocated space.
It reserves a block of memory by allocating
specified number of bytes from the availability
list(i.e from heap).
It allocates a block of contiguous bytes.
 30
 malloc():Syntax
 ptr is a pointer
 variable of type
 data_type
 ptr = (data_type*)malloc(size);
 size is the number of
data_type can be any
 bytes required
of the basic data type
 or user defined data
 type
 31
 malloc():Return Value
On success,malloc() returns a pointer of type void
to the newly allocated block memory.
By typecasting appropriately it can be used to
store the data appropriately.
If the specified size of memory is not available,
the function returns a NULL.
 32
 malloc():An Example
void main()
{
 char *str;
 if(str=(char *)malloc(10)==NULL)
 {
 printf(“Out of memory\n”);
 exit(1);
 }
 strcpy( str,”Hello”);
 printf(“String is %s\n”,str);
 free(str);
}
 33
 calloc()
The function allocates multiple blocks of
same size,initializes all locations to zero
and returns a pointer to the first byte of the
allocated space.
It allocates a block of contiguous bytes.
 34
 calloc():Syntax
 ptr is a pointer
 variable of type
 data_type
 ptr = (data_type*)calloc(n,size);
data_type can be any size is the number
 ‘n’ is the number
of the basic data type of bytes required
 of blocks to be
 or user defined data allocated if size
 type bytes
 35
 calloc():Return Value
It returns a pointer to the newly allocated
block.
The total number of bytes allocated is equal
to n*size and each location in the allocated
memory is initialized to zero.
If the specified size of memory is not
available, the function returns a NULL.
 36
 calloc():An Example
void main()
{
 char *str = NULL;
 str=(char *)calloc(10,sizeof(char));
 if(str==NULL)
 {
 printf(“Out of memory\n”);
 exit(1);
 }
 strcpy( str,”Hello”);
 printf(“String is %s\n”,str);
 free(str); }
 37
 realloc()
• This function is used to alter the size of the
 previously allocated space which is allocated
 either by using malloc or calloc functions.
• This function guarantees that reallocating the
 memory will not destroy the original contents of
 memory.
• The contents of the old block will be copied into a
 newly allocated space and so,this function
 guarantees that the earlier contents are not lost.
 38
 realloc():Syntax
 The address of the
 newly allocated
 memory after
 reallocation
ptr = (data_type*)realloc(ptr,size);
data_type can be any size is the
 Starting address
of the basic data type number of bytes
 of allocated
 or user defined data required for
 memory obtained
 type reallocation
 previously
 39
 realloc():Return Value
On success,the function returns the address
of reallocated block of memory.
The address returned may be different from
the original address.
If reallocation fails or if size specified is
zero,the function return NULL and the
original block is freed.
 40
void main() realloc():An Example
{
 char *str;
 str=(char *)malloc(10);
 strcpy( str,”Embedded”);
 printf(“Address of String %s is %d\n”,str,str);
 str=(char *)realloc(str,40);
 strcpy( str,”System Design”);
 printf(“Address of String %s is %d\n”,str,str);
 free(str);
 }
 41
 free()
This function is used to release the memory space
that has been allocated earlier.
This function de-allocates the allocated block of
memory which is allocated by using the functions
malloc,calloc and realloc.
It is the responsibility of the programmer to de-
allocate memory whenever it is not require by the
application.
 42
free():Syntax and Return Value
 ptr is a pointer to a
 memory block which
 has already been
 created
 free(ptr);
 There is no return value for the
free() function.
 43
 Differences:malloc() & calloc()
 malloc() calloc()
The syntax of malloc is The syntax of calloc is
ptr=(data_type*)malloc(size); ptr=(data_type*)calloc(n,size);
Allocates a contiguous block of Allocates multiple blocks of
memory of specified size. memory,each block with the
Allocated space will not be same size.
initialized. Each byte of allocated space is
Time efficiency is higher than initialized to zero.
calloc(). It is more expensive in time
 efficiency because of zero
 initialization.
 44
 Memory Leakage
main()
{
 int a;
 a=(int*)malloc(sizeof(int));
 *a=10;
 10
 a=(int*)malloc(sizeof(int));
 20
 *a=20;
 }
• Allocation of memory is done twice.In this case, a contains the
address of the most recently allocated memory.
• The earlier allocated memory remains inaccessable.
• The problem where in memory is reserved but not accessible to any
application is called MEMORY LEAKAGE.
 45
 Dangling Pointer
main()
{
 int *a;
 a=(int*)malloc(sizeof(a));
 20
 *a=20;
 free(a); ?
 ……;
 ……;
}
 46
 Dangling Pointer
• After de-allocating the memory for the variable using the free() function,the
 memory location pointing to by it is returned to the availability list.
• The pointer variable can be used, but the contents pointing to that cannot be used.
• The pointer variable does not contain a valid address and is called as a Dangling
 Pointer.
• We should store a NULL immediately after executing the free() function.
• Any pointer pointing to a destroyed object or which does not contain a valid
 address is called a Dangling Pointer.
• All un-initialized local pointer variables in a function do not contain valid
 addresses and are all considered as Dangling Pointers.
• It is a very good programming practice to initialize all dangling pointers to NULL
 immediately after freeing the location allocated earlier.
 47
 Summary
A preprocessor is a facility provided for writing
portable programs, easier program modifications
and easier debugging.
A preprocessor processes the source code
program before it passes through the compiler.
A macro is a simple function having its own
syntax using #define,
Dynamic memory allocation is the process of
allocating memory space during run time.
 48
Thank You!
 49