C programming Language Chapter 6 Dynamic Memory Allocation
- Slides: 42
C programming Language Chapter 6: Dynamic Memory Allocation (DMA) ספטמבר 04 Copyright Meir Kalech 1
What is Dynamic Memory Allocation? n The problem: Array definition: its size must be known at compilation time. The array, when used, may be either too small – not enough room for all the elements, or too big – so it’s a waste of memory. n The solution: Use Dynamic Memory Allocation (DMA): create the array at run-time, after determining the required number of elements. n Dynamic memory allocation enables the programmer to: n Request exactly the required amount of memory. n Release the allocated memory when it is no longer needed. ספטמבר 04 Copyright Meir Kalech 2
malloc Function n n malloc function enables to allocate memory at run-time. Syntax: malloc(number of requested bytes); Example: int size; printf(“how many integers? ”); scanf(“%d”, &size); malloc(size*sizeof(int)); Comment: All the allocation functions use the <alloc. h> library. ספטמבר 04 Copyright Meir Kalech 3
calloc Function n calloc function enables to allocate memory at run time. n n The allocated memory is initialized (cleared) with zeros. Syntax: calloc(number of elements, size of each element); Example: int size; printf(“how many integers? ”); scanf(“%d”, &size); calloc(size, sizeof(int)); ספטמבר 04 Copyright Meir Kalech FINE! But I can’t access the allocated memory!? 4
Allocation n malloc and calloc return the first address of the allocated memory. Upon failure, they return NULL (0). We can save the return value in a pointer, and access the memory by using the operator * or operator []. For instance: DON’T int size; WORRY!!! Pointers will int *pointer; help you! printf(“how many integers? ”); scanf(“%d”, &size); pointer = malloc(size*sizeof(int)); if(pointer != NULL) pointer[0] = 54; ספטמבר 04 Copyright Meir Kalech 5
Allocation pointer = malloc(size*sizeof(int)); Problem: What type does malloc return? int *, char *, float * ? ? ? Answer: void * !!! void * may be changed to any pointer type by using casting. pointer = (int *) malloc(size*sizeof(int)); ספטמבר 04 Copyright Meir Kalech 6
Heap n n n Where is the memory allocated? Reminder: we studied about the “stack segment” and “data segment”. Stack segment is dedicated to local variables. Allocated memory is not a local variable. Conclusion: dynamic memory is allocated in the data segment (heap). int *p = (int *) malloc(5*sizeof(int)); Stack segment: p: 100 ספטמבר 04 500 Data segment: 500 ? ? ? Copyright Meir Kalech 7
Comment BE CAREFUL: A pointer that points to allocated memory can be mistakenly assigned to another memory address. In this case, we might lose our connection to the previously allocated memory. int *p = (int *) malloc(5*sizeof(int)); Stack segment: p: 100 500 ספטמבר 04 Data segment: 500 ? ? ? Copyright Meir Kalech 8
Comment BE CAREFUL: A pointer that points to allocated memory can be mistakenly assigned to another memory address. In this case, we might lose our connection to the previously allocated memory. int *p = (int *) malloc(5*sizeof(int)); int arr[3]; p = arr; Stack segment: 500 p: 100 200 arr: 200 ספטמבר 04 Data segment: ? ? ? NOW NOT ACCESSIBLE!! Copyright Meir Kalech 9
Comment To avoid this problem, we can first save the address in another pointer: int *save, *p = (int *) malloc(5*sizeof(int)); int arr[3]; save = p; p = arr; Stack segment: save: 300 p: 100 200 arr: 200 ספטמבר 04 500 ? ? ? Data segment: 500 ? ? ? ACCESSIBLE through save Copyright Meir Kalech 10
free Function n n Since dynamic memory is allocated in the data segment, it is not deleted when the end of a block is reached, but it’s the programmer responsibility to explicitly delete it. The free function gets the first address of an allocated memory, and frees it: n Syntax: free(first_address); ספטמבר 04 Copyright Meir Kalech 11
free Function int *p 1, *p 2; p 1 = (int *) malloc(5*sizeof(int)); p 2 = (int *) malloc(3*sizeof(int)); free(p 2); free(p 1); Stack segment: p 1: 100 500 p 2: 200 300 ספטמבר 04 Data segment: 500 ? ? ? 300 ? ? ? Copyright Meir Kalech 12
free Function int *p 1, *p 2; p 1 = (int *) malloc(5*sizeof(int)); p 2 = (int *) malloc(3*sizeof(int)); free(p 2); free(p 1); Stack segment: Data segment: p 1: 100 500 p 2: 200 300 ספטמבר 04 Copyright Meir Kalech 13
free Function BE CAREFUL!!! Avoid freeing memory that is already freed (execution error) Stack segment: int *p 1, *p 2; p 1 = (int *) malloc(5*sizeof(int)); p 2 = (int *) malloc(3*sizeof(int)); free(p 2); free(p 1); Data segment: p 1: 100 500 p 2: 200 300 ספטמבר 04 Copyright Meir Kalech 14
free Function int *p 1, *p 2 Initialize your pointers with NULL! Now, there is no BUG. p 1 = (int *) malloc(5*sizeof(int)); p 2 = (int *) malloc(3*sizeof(int)); free(p 2); free(p 1); p 1=NULL; free(p 1); Stack segment: p 1: 100 Data segment: 0 p 2: 200 300 ספטמבר 04 Copyright Meir Kalech 15
String Allocation n For array allocation, the programmer gets the size from the user. On the other hand, for string allocation, it doesn’t make sense to ask the user for the size, since the meaning of a string size is its number of letters. Therefore, it is common to define a buffer (of length fit for a large string) to store the input string and allocate memory according to the size of the input string. ספטמבר 04 Copyright Meir Kalech 16
String Allocation char *p 1, buffer[30]; printf(“enter string”); scanf(“%s”, buffer); p 1 = (char *) malloc(strlen(buffer)+1); strcpy(p 1, buffer); free(p 1); Stack segment: p 1: 100 Data segment: ? buffer: ? ? ? … ? 200 ספטמבר 04 Copyright Meir Kalech 17
String Allocation char *p 1, buffer[30]; printf(“enter string”); scanf(“%s”, buffer); p 1 = (char *) malloc(strlen(buffer)+1); strcpy(p 1, buffer); free(p 1); Input: “zion” Stack segment: p 1: 100 buffer: z 200 ספטמבר 04 Data segment: ? i o n … ? Copyright Meir Kalech 18
String Allocation char *p 1, buffer[30]; printf(“enter string”); scanf(“%s”, buffer); p 1 = (char *) malloc(strlen(buffer)+1); strcpy(p 1, buffer); free(p 1); Stack segment: p 1: 100 500 buffer: z 200 ספטמבר 04 Data segment: 500 ? ? ? i o n … ? Copyright Meir Kalech 19
String Allocation char *p 1, buffer[30]; printf(“enter string”); scanf(“%s”, buffer); p 1 = (char *) malloc(strlen(buffer)+1); strcpy(p 1, buffer); free(p 1); Stack segment: p 1: 100 500 buffer: z i 200 ספטמבר 04 Data segment: 500 z i o n … ? Copyright Meir Kalech 20
String Allocation char *p 1, buffer[30]; printf(“enter string”); scanf(“%s”, buffer); p 1 = (char *) malloc(strlen(buffer)+1); strcpy(p 1, buffer); free(p 1); Stack segment: Data segment: p 1: 100 500 buffer: z 200 ספטמבר 04 i o n … ? Copyright Meir Kalech 21
realloc Function n One of the goals of dynamic memory allocation is to enable reallocation, namely, increase/decrease the old allocation size. There is reallocation function called realloc. n Example: n int size, size 2; int *pointer; printf(“how many integers? ”); scanf(“%d”, &size); pointer = (int *) malloc(size*sizeof(int)); if(pointer == NULL) exit(1); printf(“how many integers more? ”); scanf(“%d”, &size 2); pointer = (int *) realloc(pointer, (size+size 2)*sizeof(int)); if(pointer == NULL) exit(1); ספטמבר 04 Copyright Meir Kalech 22
realloc Function Some Comments: 1. The new size is the old + additional size. 2. The process: n If there is enough space • extend the old allocation. n Else • Allocate new size (old + additional). • Copy the old data to the new place. • Free the old allocation (should not be used anymore). Return the first address of the allocation. If the first parameter is NULL, then just malloc. n 3. ספטמבר 04 Copyright Meir Kalech 23
Array of Pointers n n The problem: Assume we want to read a list of 3 names. The names differ in length but the maximum name length is 23. First solution: char arr[3][23]; A list of names is an array of strings. Since a string is an array of char, we have a 2 D array of char. Can cause waste of memory!!! 100 S n o w w h i t e r e d r i d i n g 123 L i t t l e h o o d 146 C i n d e r e l l a ספטמבר 04 Copyright Meir Kalech 24
Array of Pointers n Second solution: char *arr[3]; arr is array of 3 elements, where each of them is a pointer to char. Now each element can point to a different char array of a different size. arr: 100 200 340 730 ספטמבר 04 S n L i C o w w h t t l e i n d e i t r e d r e l e r i d i n g l h o o d a Copyright Meir Kalech 25
Pointer to Pointer n n Sometimes the number of rows (names) is unknown ahead of time. In this case, we should allocate both the rows as well as the elements of each vector: 1. 2. Allocate array of pointers. Allocate each pointer in the array. ספטמבר 04 Copyright Meir Kalech 26
Pointer to Pointer pp. Char: 100 0 buffer: 900 num: 120 ? char **pp. Char = NULL, buffer[30]; int num; ? ? ? … ? ספטמבר 04 Copyright Meir Kalech 27
Pointer to Pointer pp. Char: 100 num: 120 150 3 150 0 0 char **pp. Char = NULL, buffer[30]; int num; printf(“how many names? ”); scanf(“%d”, &num); pp. Char = (char **) calloc(num, sizeof(char *)); INPUT: 3 0 buffer: 0 0 0 … 0 900 ספטמבר 04 Copyright Meir Kalech 28
Pointer to Pointer pp. Char: 100 num: 120 150 3 150 200 S N 0 0 O W char **pp. Char = NULL, buffer[30]; int num, i; printf(“how many names? ”); scanf(“%d”, &num); pp. Char = (char **) calloc(num, sizeof(char *)); for(i=0; i<num; i++) { scanf(“%s”, buffer); pp. Char[i] = (char *) malloc(strlen(buffer)+1); strcpy(pp. Char[i], buffer); } buffer: S N O W … 0 900 ספטמבר 04 Copyright Meir Kalech 29
Pointer to Pointer num: 120 pp. Char: 100 3 150 200 340 S N O W R E D 0 char **pp. Char = NULL, buffer[30]; int num, i; printf(“how many names? ”); scanf(“%d”, &num); pp. Char = (char **) calloc(num, sizeof(char *)); for(i=0; i<num; i++) { scanf(“%s”, buffer); pp. Char[i] = (char *) malloc(strlen(buffer)+1); strcpy(pp. Char[i], buffer); } buffer: R E D ? … 0 900 ספטמבר 04 Copyright Meir Kalech 30
Pointer to Pointer char** pp. Char = NULL, buffer[30]; int num, i; printf(“how many names? ”); scanf(“%d”, &num); pp. Char = (char **) calloc(num, sizeof(char *)); for(i=0; i<num; i++) { scanf(“%s”, buffer); pp. Char[i] = (char *) malloc(strlen(buffer)+1); strcpy(pp. Char[i], buffer); } num: 120 pp. Char: 100 3 150 200 340 S N O W R E D C I N 490 buffer: 900 C I ספטמבר 04 N D E R E D E L R L E A L L A … ? Copyright Meir Kalech 31
Pointer to Pointer - free for(i=0; i<num; i++) free(pp. Char[i]); num: 120 pp. Char: 100 3 150 200 340 490 buffer: 900 C I ספטמבר 04 N D S N O W R E D C I N E R E D E L R L E A L L A … ? Copyright Meir Kalech 32
Pointer to Pointer - free for(i=0; i<num; i++) free(pp. Char[i]); num: 120 pp. Char: 100 3 150 200 340 490 buffer: 900 C I ספטמבר 04 N D E R E L L A … ? Copyright Meir Kalech 33
Pointer to Pointer - free pp. Char: 100 num: 120 150 buffer: 900 for(i=0; i<num; i++) free(pp. Char[i]); free(pp. Char); 3 C I ספטמבר 04 N D E R E L L A … ? Copyright Meir Kalech 34
Dynamic Memory Allocation - Function n n How to allocate memory in a function? Problem: indeed DMA lifetime does not depend on the function, but the scope and lifetime of the pointer to the memory is only in the function! So how to use the allocated memory also outside the function? Solution: n n Return the pointer from the function. Pass the pointer by address. ספטמבר 04 Copyright Meir Kalech 35
Problem void func() HEAP: { int *p; 100 p = (int *) calloc(3, sizeof(int)); 0 } void main() { func(); // how to use p here? ? ? STACK: } 0 0 main ספטמבר 04 Copyright Meir Kalech 36
Return Address int *func() HEAP: { int *p; 100 p = (int *) calloc(3, sizeof(int)); 0 return p; } void main() { int *pm = func(); STACK: } 0 0 main pm: 250 100 ספטמבר 04 Copyright Meir Kalech 37
Pass Address void func(int *p) HEAP: { p = (int *) calloc(3, sizeof(int)); } void main() { int* pm = NULL; func(pm); // how to use p here? ? ? STACK: } main pm: 250 ספטמבר 04 Copyright Meir Kalech 0 38
Pass Address HEAP: void func(int *p) { p = (int *) calloc(3, sizeof(int)); } void main() { int *pm = NULL; func(pm); // how to use p here? ? ? STACK: } main pm: 250 0 func p: 400 ספטמבר 04 Copyright Meir Kalech 0 39
Pass Address void func(int *p) HEAP: { 100 p = (int *) calloc(3, sizeof(int)); } 0 void main() { int *pm = NULL; func(pm); } 0 0 STACK: main pm: 250 0 func p: 400 ספטמבר 04 Copyright Meir Kalech 100 40
Pass Address – Right Way void func(int **p) HEAP: { *p = (int *) calloc(3, sizeof(int)); } void main() { int *pm = NULL; func(&pm); } STACK: main pm: 250 0 func p: 400 ספטמבר 04 Copyright Meir Kalech 250 41
Pass Address – Right Way void func(int **p) HEAP: { 100 *p = (int *) calloc(3, sizeof(int)); } 0 void main() { int *pm = NULL; func(&pm); } 0 0 STACK: If a parameter (pointer) is changed in a function (“p =“), it must be passed by address. If its pointed value is changed (“p[i] =“), it can be passed by value. ספטמבר 04 Copyright Meir Kalech main pm: 250 100 func p: 400 250 42
- Example of dynamic memory allocation
- Explicit memory allocation
- Malloc function
- Dynamic memory allocation
- Example of dynamic memory allocation
- Dynamic memory allocation in data structure
- Dynamic memory allocation in data structure
- Dynamic c programming
- Alokasi memori dinamis c++
- Dynamic memory allocation in java
- Calloc example
- Greedy vs dynamic programming
- Contiguous allocation vs linked allocation
- Dynamic strategies for asset allocation
- Dynamic storage-allocation problem
- Polymorphism dynamic allocation
- Assumptions for dynamic channel allocation
- Dynamic storage allocation
- 0 0005
- Buddy memory allocation
- Single user contiguous scheme example
- Demand paged memory allocation
- First fit memory allocation
- External fragmentation
- Paging in non contiguous memory allocation
- What are two goals of multitasking memory allocation
- Non contiguous memory allocation
- Non contiguous memory allocation
- Q concepts
- Non contiguous memory allocation
- Bitmap and linked list in os
- Memory allocation
- Zig memory allocation
- Memory allocation policy
- Cs 537
- What is hardware description language
- Transferered
- Synchronous dynamic ram
- Kernel dynamic memory
- Dynamic memory management
- Dynamic memory management
- Prototypes in semantics
- Explicit memory