Preprocessor Directories And Memory Allocation: Session 06

  • Uploaded by: jack_harish
  • 0
  • 0
  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Preprocessor Directories And Memory Allocation: Session 06 as PDF for free.

More details

  • Words: 2,124
  • Pages: 49
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

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 • 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 int j; for(j=1;j<=VALUE;j++) printf(“%d”,i); }

expansion

NOTE:In a macro call the preprocessor replaces the macro template with its macro expansion. 12

Differences:Macros & Functions Macros • • • • •

They are expanded at precompile time. They are expanded by the preprocessor. They do not follow any rules.It is merely a replacement. Expressions passed as arguments can be evaluated more than once. Code used by macros cannot be used for debugging.

Functions • • • •



They are expanded at compile time. They are parsed by the compiler. They follow all the rules enforced on functions. Expressions passed as arguments are evaluated only once. 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 ifelse-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

main() {

Pseudo Code #if VALUE == 5 statement #elif statement #elif statement #else statement #endif

1; 2; 3; 4;

}

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
}

{

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 Variables . Free Memory . Global/Static Variables C Program BIOS

Stack Heap Memory

RAM 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);

data_type can be any of the basic data type or user defined data type

size is the number of bytes required

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 of the basic data type or user defined data type

‘n’ is the number of blocks to be allocated if size bytes

size is the number of bytes required

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 of the basic data type or user defined data type

Starting address of allocated memory obtained previously

size is the number of bytes required for reallocation 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 deallocate 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() The syntax of malloc is ptr=(data_type*)malloc(size); Allocates a contiguous block of memory of specified size. Allocated space will not be initialized. Time efficiency is higher than calloc().

calloc() The syntax of calloc is ptr=(data_type*)calloc(n,size); Allocates multiple blocks of memory,each block with the same size. Each byte of allocated space is initialized to zero. It is more expensive in time efficiency because of zero initialization.

44

Memory Leakage main() { int a; a=(int*)malloc(sizeof(int)); *a=10; a=(int*)malloc(sizeof(int)); *a=20;

10 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)); *a=20; free(a);

20 ?

……; ……; }

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

Related Documents