Download presentation
Presentation is loading. Please wait.
1
1 מבוא למדעי המחשב הקצאה דינאמית
2
2 הקצאת זיכרון דינאמית כאשר אנו משתמשים במערכים, אנו מקצים אוטומטית את הזיכרון המקסימלי שנצטרך. בפועל, אנו משתמשים בהרבה פחות זיכרון. זהו אקט בזבזני מבחינת כמות הזיכרון הדרושה ביחס לזו הנצרכת בפועל. הפתרון - הקצאת זיכרון דינאמית ע"י שימוש בפוינטרים.
3
3 הקצאת זיכרון דינאמית - דוגמא מערך דו-ממדי: char month[13][15]={“illegal_month”,”January”,”February”,…,”December”} מערך של פוינטרים: char *pmonth[ ]={“Illegal”,”January”,”February”,…,”December”} illegal _ month\0 January F e b ruar y D ecem b er 0 1 2 12 illegal _ month\0 January F e b ruar y D ecem b er 0 1 2 12
4
4 הקצאת זיכרון דינאמית בזמן ריצה שימוש בפוינטרים. הגדרת פוינטר בראשית הפונקציה – תופס רק את מספר הבתים המוקצים למצביע. קביעת גודל הזיכרון אליו מצביע הפוינטר בזמן ריצה – כאשר ידוע גודל הזיכרון הדרוש. הקצאת זיכרון ← ע"י הפונקציה malloc. שחרור הזיכרון ← ע"י הפונקציה free.
5
5 הפונקציה malloc הגדרת הפונקציה: void *malloc (size_t size) הפונקציה מוגדרת ב- הפונקציה מקצה בלוק בגודל size בתים בזיכרון בזמן ריצת התכנית. אם הקצאת הזיכרון הצליחה הפונקציה מחזירה מצביע לתחילת הבלוק המוקצה. המצביע אשר הפונקציה מחזירה הוא מטיפוס void*, כלומר מצביע מטיפוס לא ידוע, לכן יש לבצע casting (המרה של המצביע לטיפוס הרצוי). כאשר הקצאת הזיכרון לא מצליחה (אין מספיק זיכרון רציף פנוי בזמן הריצה) הפונקציה מחזירה NULL. לכן, לאחר כל הקצאה דינאמית יש לבדוק שהפונקציה החזירה ערך השונה מ-NULL.
6
6 הפונקציה free הגדרת הפונקציה: void free (void *block) הפונקציה מוגדרת ב- הפונקציה משחררת את הבלוק המוקצה מן הזיכרון, כך שניתן יהיה להקצותו מחדש. במידה ולא נפעיל את הפונקציה בסיום השימוש בבלוק, לא נוכל להשתמש בזיכרון שלא שוחרר במשך כל זמן ריצת התכנית. הזיכרון המוקצה ישוחרר ע"י מערכת ההפעלה בסיום ביצוע התכנית.
7
תכנית דוגמא /* malloc.c - a program demonstrating memory allocation */ #include int SetSize (void); int* CreateArray (int size); void PrintArray(int a[], int size); int main() { int i, len, *array; len=SetSize(); array=CreateArray(len); for (i=0; i< len; i++) array[i]=i; PrintArray(array, len); free(array); return 0; }
8
תכנית דוגמא int SetSize (void) { int size; printf("Please enter array size\n"); if (scanf("%d",&size)!=1){ printf("Error reading array size\n"); exit (1); } if (size<1){ printf("Array size too small\n"); exit (1); } return size; }
9
תכנית דוגמא int* CreateArray (int size) { int *array; array=(int *) malloc(size*sizeof(int)); if (array==NULL){ printf("Error in memory allocation\n"); exit (1); } return array; }
10
תכנית דוגמא void PrintArray(int a[], int size) { int i; for (i=0; i< size; i++) printf("%d ",a[i]); printf("\n"); return; }
11
11 תכנית דוגמא ( 2 ) – חיבור מטריצות המטרה: לשנות את התכנית שכתבנו עבור חיבור מטריצות כך שתעבוד עם הקצאה דינאמית. מעבר ממערך דו-ממדי למערך חד ממדי: row col 0 1 ן 01 j 01 … i*col+j
12
חיבור מטריצות – ללא הקצאה דינאמית int main() { int a[SIZE][SIZE], b[SIZE][SIZE], c[SIZE][SIZE]; int row1, row2, col1, col2; ReadMatrix(a, &row1, &col1); ReadMatrix(b, &row2, &col2); if (add(a,row1,col1,b,row2,col2,c)==FALSE) { printf("Matrices cannot be added\n"); return 0; } else{ printf("The result matrix:\n"); PrintMatrix(c,row1,col1); } return 0; }
13
חיבור מטריצות – עם הקצאה דינאמית int main() { int *a, *b, *c; int row1, row2, col1, col2; ReadMatrix(&a, &row1, &col1); ReadMatrix(&b, &row2, &col2); if (add(a,row1,col1,b,row2,col2,&c)==FALSE) { printf("Matrices cannot be added\n"); return 0; } else{ printf("The result matrix:\n"); PrintMatrix(c,row1,col1); } return 0; }
14
חיבור מטריצות – ללא הקצאה דינאמית /* read a matrix*/ void ReadMatrix (int a[SIZE][SIZE], int *row, int *col) { int i,j; printf("Please enter the number of rows and columns:\n"); if (scanf("%d%d",row,col)!=2){ printf("Input error"); exit (1); } CheckSize (*row); CheckSize (*col); printf("Please enter matrix [%d][%d]\n",*row,*col); for (i=0; i < *row; i++) { for (j=0; j < *col; j++) { if(scanf("%d", &(a[i][j]))!=1){ printf("Input error"); exit (1); } PrintMatrix(a, *row, *col); return; }
15
חיבור מטריצות – עם הקצאה דינאמית void ReadMatrix (int **a, int *row, int *col) { int i,j,place; printf("Please enter the number of rows and columns:\n"); if (scanf("%d%d",row,col)!=2){ printf("Input error"); exit (1); } CheckSize (*row); CheckSize (*col); *a=CreateArray((*row) * (*col)); printf("Please enter matrix [%d][%d]\n",*row,*col); for (i=0; i < *row; i++) { for (j=0; j < *col; j++) { place=i*(*col)+j; if(scanf("%d", *a+place)!=1){ printf("Input error\n"); exit (1); } PrintMatrix(*a, *row, *col); return; }
16
חיבור מטריצות – ללא / עם הקצאה דינאמית /* Check a matrix dimension*/ void CheckSize (int size) { if (size<0){ printf( “ Matrix dimensions should be positive\n"); exit (1); } return; }
17
חיבור מטריצות – ללא הקצאה דינאמית /* print a matrix */ void PrintMatrix (int a[SIZE][SIZE], int row, int col) { int i,j; printf("Printing matrix [%d][%d]\n", row, col); for (i=0; i < row; i++) { for (j=0; j < col; j++) { printf("%6d", a[i][j]); } printf("\n"); }
18
חיבור מטריצות – עם הקצאה דינאמית /* print a matrix */ void PrintMatrix (int a[], int row, int col) { int i,j,place; printf("Printing matrix [%d][%d]\n", row, col); for (i=0; i < row; i++) { for (j=0; j < col; j++) { place=i*col+j; printf("%6d", a[place]); } printf("\n"); }
19
חיבור מטריצות – ללא הקצאה דינאמית /* add two matrices */ int add (int a[SIZE][SIZE], int row1, int col1, int b[SIZE][SIZE], int row2, int col2, int c[SIZE][SIZE]) { int i,j; if ( (col1!=col2) || (row1!=row2) ) return FALSE; for (i=0; i < row1; i++) for (j=0; j < col2; j++) c[i][j]=a[i][j]+b[i][j]; return TRUE; }
20
חיבור מטריצות – עם הקצאה דינאמית /* add two matrices */ int add (int *a, int row1, int col1, int *b, int row2, int col2, int **c) { int i,j,place; if ( (col1!=col2) || (row1!=row2) ) return FALSE; *c=CreateArray((row1) * (col1)); for (i=0; i < row1; i++){ for (j=0; j < col1; j++){ place=i*col1+j; *(*c+place)=a[place]+b[place]; } return TRUE; }
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.