180 likes | 318 Views
C Programming – Part 7 Memory Management. TEC 284. Memory. Software and operating systems use a variety of memory implementations, including virtual memory and RAM RAM (Random Access Memory) is a volatile solution for allocating, storing and retrieving data
E N D
C Programming – Part 7 Memory Management TEC 284
Memory • Software and operating systems use a variety of memory implementations, including virtual memory and RAM • RAM (Random Access Memory) is a volatile solution for allocating, storing and retrieving data • When the computer loses power or shuts down, information stored in RAM is lost • Virtual memory is a reserved section on the hard disk in which the OS can swap memory segments • Virtual memory is not as efficient as RAM but gives the illusion to the CPU that is has more memory than it actually does
Stack and Heap • Using a combination of RAM and virtual memory, all software programs use their own area of memory called the stack • Every time a function is called in a program, the function’s variables and parameters are pushed onto the program’s memory stack and then pushed off or “popped” when the functions has completed or returned • Memory stacks are dynamic groupings of memory that grow and shrink as each program allocates and deallocates memory
Heap • After software programs have terminated, memory is returned for reuse for other programs • This realm of unallocated memory is managed by the Operating System (OS) and is referred to as the heap • Programs that use malloc(), calloc() and realloc() use the heap • In C we must strive to be efficient as possible and return memory to the heap when it is not being used • Especially with microcontrollers where memory is limited, we must use memory efficiently
sizeof • This allows a developer to know how many bytes are used to store integers, doubles, floats etc • sizeof operator takes a variable name or data type as an argument and returns the number of bytes required to store the data in memory int x; //valid variable name printf(“Size of integer: %dbytes\n”,sizeof(x)); //valid data type printf(“Size of integer: %dbytes\n”,sizeof(int));
Determining the size of an array int array[10]; printf(“Size of array %dbytes\n”,sizeof(array)); printf(“Number of elements in array : ”); printf(“%d\n”, sizeof(array) / sizeof(int));
malloc() • There may be occasions where fixed-sized arrays are not large enough to hold the amount of data that you want to store • malloc() allows you to create dynamic memory • The malloc() function is a part of the <stdlib.h> standard library • malloc() attempts to retrieve designated memory segments from the heap and returns a pointer that is a starting point for the memory reserved
Use of malloc() char *name; //Allocates memory for 80 chars for name name = (char*)malloc(80 * sizeof(char)); • Always check to see that malloc() was successful before attempting to use the memory • If the pointer is NULL, malloc() was not successful in allocating the memory
Use of malloc() with error checking char *name; //Allocates memory for 80 chars for name name = (char*)malloc(80 * sizeof(char)); if(name==NULL) { printf(“Out of memory\n”); } else { printf(“Memory allocated\n”); }
Managing strings with malloc() char *name; //Allocates memory for 80 chars for name name = (char*)malloc(80 * sizeof(char)); if(name!=NULL) { printf(“Enter your name: \n”); gets(name); printf(“\nHi %s\n”, name); }
Freeing memory • Good programming practice dictates that you free memory after using it • The free() function is used • It takes a pointer as an argument • This allows the system to reuse the memory for other software applications or other malloc()
Use of free() char *name; //Allocates memory for 80 chars for name name = (char*)malloc(80 * sizeof(char)); if(name!=NULL) { printf(“Enter your name: \n”); gets(name); printf(“\nHi %s\n”, name); //Free memory resources free(name); }
Freeing memory • If you forget to release allocated or used memory, typically operating systems will clean it up for you • It is good practice however to manually free memory • Failure to release memory in a program can result in wasted memory that is not returned to the heap, known as memory leak
Working with memory segments • Memory segments acquired by malloc() can be treated like array members • These can be referenced by indexes int *numbers; numbers = (int *)malloc(5 * sizeof(int)); numbers[0]=100; numbers[1]=200; numbers[2]=500; numbers[3]=400; numbers[4]=300;
calloc() • calloc() is similar to malloc() • It is part of the standard library <stdlib.h> • calloc() takes two arguments – the first is the number of memory segments needed and the second is the size of the data type int *numbers; numbers = (int *)calloc(5 , sizeof(int)); • The main benefit of using calloc() rather than malloc() is that calloc() initializes memory segments to 0 (zero) • With malloc() requires that the programmer initialize memory before using it
realloc() • calloc() and malloc() fall short in being able to expand memory that was originally allocated • E.g. You have allocated 5 integer memory segments with malloc() and you want to add 5 more memory segments while preserving the original contents • realloc() provides a way to expand continguous blocks of memory while preserving the orignal contents
realloc() • Possible outcomes of realloc() • There are times when expanding contiguous memory is not possible with the original pointer location, so realloc(), will seek out another area in memory where it can allocate the contiguous memory needed • In this case realloc() will copy the original contents to the new location and return a new pointer to the new location
realloc() example int *number, *newNumber; number =malloc(5 * sizeof(int)); if (number !=NULL ) { number[0]=100; number[1]=200; number[2]=500; number[3]=400; number[4]=300; } newNumber = realloc(number, 10 * sizeof(int)); if(newNumber !=NULL) { //more processing }