Presentation is loading. Please wait.

Presentation is loading. Please wait.

ספטמבר 04Copyright Meir Kalech1 C programming Language Chapter 6: Dynamic Memory Allocation (DMA)

Similar presentations


Presentation on theme: "ספטמבר 04Copyright Meir Kalech1 C programming Language Chapter 6: Dynamic Memory Allocation (DMA)"— Presentation transcript:

1 ספטמבר 04Copyright Meir Kalech1 C programming Language Chapter 6: Dynamic Memory Allocation (DMA)

2 ספטמבר 04Copyright Meir Kalech2 What is Dynamic Memory Allocation? 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. The solution: Use Dynamic Memory Allocation (DMA): create the array at run-time, after determining the required number of elements. Dynamic memory allocation enables the programmer to: Request exactly the required amount of memory. Release the allocated memory when it is no longer needed.

3 ספטמבר 04Copyright Meir Kalech3 malloc Function 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 library.

4 ספטמבר 04Copyright Meir Kalech4 calloc Function calloc function enables to allocate memory at run time. 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)); FINE! But I can ’ t access the allocated memory!?

5 ספטמבר 04Copyright Meir Kalech5 Allocation 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: int size; int *pointer; printf(“how many integers?”); scanf(“%d”, &size); pointer = malloc(size*sizeof(int)); if(pointer != NULL) pointer[0] = 54; DON ’ T WORRY!!! Pointers will help you!

6 ספטמבר 04Copyright Meir Kalech6 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));

7 ספטמבר 04Copyright Meir Kalech7 Heap 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). Data segment:Stack segment: 500 p: 100 ????? 500 int *p = (int *) malloc(5*sizeof(int));

8 ספטמבר 04Copyright Meir Kalech8 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. Data segment:Stack segment: 500 p: 100 ????? 500 int *p = (int *) malloc(5*sizeof(int));

9 ספטמבר 04Copyright Meir Kalech9 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. Data segment:Stack segment: 200 p: 100 ????? 500 ??? arr: 200 NOW NOT ACCESSIBLE!! int *p = (int *) malloc(5*sizeof(int)); int arr[3]; p = arr;

10 ספטמבר 04Copyright Meir Kalech10 Comment To avoid this problem, we can first save the address in another pointer: Data segment: Stack segment: 200 p: 100 ????? 500 ??? arr: 200 ACCESSIBLE through save 500 save: 300 int *save, *p = (int *) malloc(5*sizeof(int)); int arr[3]; save = p; p = arr;

11 ספטמבר 04Copyright Meir Kalech11 free Function 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: Syntax: free(first_address);

12 ספטמבר 04Copyright Meir Kalech12 free Function Data segment: Stack segment: 500 p1: 100 ????? 500 int *p1, *p2; p1 = (int *) malloc(5*sizeof(int)); p2 = (int *) malloc(3*sizeof(int)); free(p2); free(p1); 300 p2: 200 300 ???

13 ספטמבר 04Copyright Meir Kalech13 free Function Data segment: Stack segment: 500 p1: 100 int *p1, *p2; p1 = (int *) malloc(5*sizeof(int)); p2 = (int *) malloc(3*sizeof(int)); free(p2); free(p1); 300 p2: 200

14 ספטמבר 04Copyright Meir Kalech14 free Function Data segment: Stack segment: 500 p1: 100 300 p2: 200 BE CAREFUL!!! Avoid freeing memory that is already freed (execution error) int *p1, *p2; p1 = (int *) malloc(5*sizeof(int)); p2 = (int *) malloc(3*sizeof(int)); free(p2); free(p1);

15 ספטמבר 04Copyright Meir Kalech15 free Function Data segment: Stack segment: 0 p1: 100 300 p2: 200 int *p1, *p2 p1 = (int *) malloc(5*sizeof(int)); p2 = (int *) malloc(3*sizeof(int)); free(p2); free(p1); p1=NULL; free(p1); Initialize your pointers with NULL! Now, there is no BUG.

16 ספטמבר 04Copyright Meir Kalech16 String Allocation 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.

17 ספטמבר 04Copyright Meir Kalech17 String Allocation Data segment: Stack segment: ? p1: 100 ? … ????? char *p1, buffer[30]; printf( “ enter string ” ); scanf( “ %s ”, buffer); p1 = (char *) malloc(strlen(buffer)+1); strcpy(p1, buffer); free(p1); buffer: 200

18 ספטמבר 04Copyright Meir Kalech18 char *p1, buffer[30]; printf( “ enter string ” ); scanf( “ %s ”, buffer); p1 = (char *) malloc(strlen(buffer)+1); strcpy(p1, buffer); free(p1); String Allocation Data segment: Stack segment: ? p1: 100 ? … \0 noiz buffer: 200 Input: “ zion ”

19 ספטמבר 04Copyright Meir Kalech19 char *p1, buffer[30]; printf( “ enter string ” ); scanf( “ %s ”, buffer); p1 = (char *) malloc(strlen(buffer)+1); strcpy(p1, buffer); free(p1); String Allocation Data segment: Stack segment: 500 p1: 100 ? … \0 noiz buffer: 200 ? ???? 500

20 ספטמבר 04Copyright Meir Kalech20 char *p1, buffer[30]; printf( “ enter string ” ); scanf( “ %s ”, buffer); p1 = (char *) malloc(strlen(buffer)+1); strcpy(p1, buffer); free(p1); String Allocation Data segment: Stack segment: 500 p1: 100 ? … \0 noiz buffer: 200 \0 noiz 500

21 ספטמבר 04Copyright Meir Kalech21 char *p1, buffer[30]; printf( “ enter string ” ); scanf( “ %s ”, buffer); p1 = (char *) malloc(strlen(buffer)+1); strcpy(p1, buffer); free(p1); String Allocation Data segment: Stack segment: 500 p1: 100 ? … \0 noiz buffer: 200

22 ספטמבר 04Copyright Meir Kalech22 realloc Function 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. Example: int size, size2; 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”, &size2); pointer = (int *) realloc(pointer,(size+size2)*sizeof(int)); if(pointer == NULL) exit(1);

23 ספטמבר 04Copyright Meir Kalech23 realloc Function Some Comments: 1. The new size is the old + additional size. 2. The process: If there is enough space extend the old allocation. 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. 3. If the first parameter is NULL, then just malloc.

24 ספטמבר 04Copyright Meir Kalech24 Array of Pointers 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 2D array of char. Can cause waste of memory!!! Snowwhite\0 Littleredridinghood Cinderella 100 123 146

25 ספטמבר 04Copyright Meir Kalech25 Array of Pointers 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. \0etihw wonS 200 340 730 \0dooh gnidir der el ttiL allere dniC 200 340 730 arr: 100

26 ספטמבר 04Copyright Meir Kalech26 Pointer to Pointer 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. Allocate array of pointers. 2. Allocate each pointer in the array.

27 ספטמבר 04Copyright Meir Kalech27 Pointer to Pointer char **ppChar = NULL, buffer[30]; int num; 0 ppChar: 100 ? num: 120 ? … ? ???? buffer: 900

28 ספטמבר 04Copyright Meir Kalech28 Pointer to Pointer char **ppChar = NULL, buffer[30]; int num; printf( “ how many names? ” ); scanf( “ %d ”, &num); ppChar = (char **) calloc(num, sizeof(char *)); 150 ppChar: 100 3 num: 120 INPUT: 3 0 0 0 150 0 … 0 0000 buffer: 900

29 ספטמבר 04Copyright Meir Kalech29 Pointer to Pointer char **ppChar = NULL, buffer[30]; int num,i; printf( “ how many names? ” ); scanf( “ %d ”, &num); ppChar = (char **) calloc(num, sizeof(char *)); for(i=0; i<num; i++) { scanf( “ %s ”, buffer); ppChar[i] = (char *) malloc(strlen(buffer)+1); strcpy(ppChar[i], buffer); } 150 ppChar: 100 3 num: 120 200 0 0 150 0 … \0 WONS buffer: 900 \0 WONS 200

30 ספטמבר 04Copyright Meir Kalech30 Pointer to Pointer 150 ppChar: 100 3 num: 120 200 340 0 150 0 … ? \0DER buffer: 900 \0 WONS 200 \0 DER 340 char **ppChar = NULL, buffer[30]; int num,i; printf( “ how many names? ” ); scanf( “ %d ”, &num); ppChar = (char **) calloc(num, sizeof(char *)); for(i=0; i<num; i++) { scanf( “ %s ”, buffer); ppChar[i] = (char *) malloc(strlen(buffer)+1); strcpy(ppChar[i], buffer); }

31 ספטמבר 04Copyright Meir Kalech31 Pointer to Pointer 150 ppChar: 100 3 num: 120 200 340 490 150 buffer: 900 \0 WONS 200 \0 DER 340 490 \0ALLERE DNIC ? … ALLERE DNIC char** ppChar = NULL, buffer[30]; int num,i; printf( “ how many names? ” ); scanf( “ %d ”, &num); ppChar = (char **) calloc(num, sizeof(char *)); for(i=0; i<num; i++) { scanf( “ %s ”, buffer); ppChar[i] = (char *) malloc(strlen(buffer)+1); strcpy(ppChar[i], buffer); }

32 ספטמבר 04Copyright Meir Kalech32 Pointer to Pointer - free for(i=0; i<num; i++) free(ppChar[i]); 150 ppChar: 100 3 num: 120 200 340 490 150 buffer: 900 \0 WONS 200 \0 DER 340 490 \0ALLERE DNIC ? … ALLERE DNIC

33 ספטמבר 04Copyright Meir Kalech33 Pointer to Pointer - free for(i=0; i<num; i++) free(ppChar[i]); 150 ppChar: 100 3 num: 120 200 340 490 150 buffer: 900 ? … \0ALLERE DNIC

34 ספטמבר 04Copyright Meir Kalech34 Pointer to Pointer - free for(i=0; i<num; i++) free(ppChar[i]); free(ppChar); 150 ppChar: 100 3 num: 120 buffer: 900 ? … \0ALLERE DNIC

35 ספטמבר 04Copyright Meir Kalech35 Dynamic Memory Allocation - Function 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: Return the pointer from the function. Pass the pointer by address.

36 ספטמבר 04Copyright Meir Kalech36 Problem void func() { int *p; p = (int *) calloc(3,sizeof(int)); } void main() { func(); // how to use p here??? } 100 HEAP: 000 STACK: main

37 ספטמבר 04Copyright Meir Kalech37 Return Address int *func() { int *p; p = (int *) calloc(3,sizeof(int)); return p; } void main() { int *pm = func(); } main HEAP: 000 STACK: pm: 250 100

38 ספטמבר 04Copyright Meir Kalech38 Pass Address void func(int *p) { p = (int *) calloc(3,sizeof(int)); } void main() { int* pm = NULL; func(pm); // how to use p here??? } main HEAP: STACK: pm: 250 0

39 ספטמבר 04Copyright Meir Kalech39 Pass Address void func(int *p) { p = (int *) calloc(3,sizeof(int)); } void main() { int *pm = NULL; func(pm); // how to use p here??? } func HEAP: STACK: main pm: 250 0 p: 400 0

40 ספטמבר 04Copyright Meir Kalech40 Pass Address void func(int *p) { p = (int *) calloc(3,sizeof(int)); } void main() { int *pm = NULL; func(pm); } HEAP: 100 000 func STACK: main pm: 250 0 p: 400 100

41 ספטמבר 04Copyright Meir Kalech41 Pass Address – Right Way void func(int **p) { *p = (int *) calloc(3,sizeof(int)); } void main() { int *pm = NULL; func(&pm); } HEAP: func STACK: main pm: 250 0 p: 400 250

42 ספטמבר 04Copyright Meir Kalech42 Pass Address – Right Way void func(int **p) { *p = (int *) calloc(3,sizeof(int)); } void main() { int *pm = NULL; func(&pm); } HEAP: 100 000 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. func STACK: main pm: 250 100 p: 400 250


Download ppt "ספטמבר 04Copyright Meir Kalech1 C programming Language Chapter 6: Dynamic Memory Allocation (DMA)"

Similar presentations


Ads by Google