1 / 19

מבוא למדעי המחשב

מבוא למדעי המחשב. הקצאת זיכרון דינאמית. הקצאת זיכרון דינאמית. כאשר אנו משתמשים במערכים, במיוחד במערכים דו-ממדיים, אנו מקצים אוטומטית את הזיכרון המקסימלי שנצטרך. בפועל, אנו משתמשים בהרבה פחות זיכרון. זהו אקט בזבזני מבחינת כמות הזיכרון הדרושה ביחס לזו הנצרכת בפועל.

lee-drake
Download Presentation

מבוא למדעי המחשב

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. מבוא למדעי המחשב הקצאת זיכרון דינאמית

  2. הקצאת זיכרון דינאמית • כאשר אנו משתמשים במערכים, במיוחד במערכים דו-ממדיים, אנו מקצים אוטומטית את הזיכרון המקסימלי שנצטרך. • בפועל, אנו משתמשים בהרבה פחות זיכרון. • זהו אקט בזבזני מבחינת כמות הזיכרון הדרושה ביחס לזו הנצרכת בפועל. • הפתרון - הקצאת זיכרון דינאמית ע"י שימוש בפוינטרים.

  3. הקצאת זיכרון דינאמית בזמן ריצה • שימוש בפוינטרים. • הגדרת פוינטר בראשית הפונקציה – תופס רק את מספר הבתים המוקצים למצביע. • קביעת גודל הזיכרון אליו מצביע הפוינטר בזמן ריצה – כאשר ידוע גודל הזיכרון הדרוש. • הקצאת זיכרון ← ע"י הפונקציה malloc. • שחרור הזיכרון ← ע"י הפונקציה free.

  4. הפונקציה malloc • הגדרת הפונקציה: void *malloc (size_t size) • הפונקציה מוגדרת ב- <stdlib.h> • הפונקציה מקצה בלוק בגודל size בתים בזיכרון בזמן ריצת התכנית. אם הקצאת הזיכרון הצליחה הפונקציה מחזירה מצביע לתחילת הבלוק המוקצה. המצביע אשר הפונקציה מחזירה הוא מטיפוס void*, כלומר מצביע מטיפוס לא ידוע, לכן יש לבצע casting (המרה של המצביע לטיפוס הרצוי). • כאשר הקצאת הזיכרון לא מצליחה (אין מספיק זיכרון רציף פנוי בזמן הריצה) הפונקציה מחזירה NULL. לכן, לאחר כל הקצאה דינאמית יש לבדוק שהפונקציה החזירה ערך השונה מ-NULL.

  5. הפונקציה free • הגדרת הפונקציה: void free (void *block) • הפונקציה מוגדרת ב- <stdlib.h> • הפונקציה משחררת את הבלוק המוקצה מן הזיכרון, כך שניתן יהיה להקצותו מחדש. • במידה ולא נפעיל את הפונקציה בסיום השימוש בבלוק, לא נוכל להשתמש בזיכרון שלא שוחרר במשך כל זמן ריצת התכנית. • הזיכרון המוקצה ישוחרר ע"י מערכת ההפעלה בסיום ביצוע התכנית.

  6. תכנית דוגמא /* malloc.c - a program demonstrating memory allocation */ #include <stdio.h> #include <stdlib.h> 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); return 0; }

  7. תכנית דוגמא void PrintArray(int a[], int size) { int i; for (i=0; i< size; i++) printf("%d ",a[i]); printf("\n"); return; }

  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. j 0 1 0 1 row ן col … 0 1 i*col+j תכנית דוגמא (2) – חיבור מטריצות • המטרה: לשנות את התכנית שכתבנו עבור חיבור מטריצות כך שתעבוד עם הקצאה דינאמית. • מעבר ממערך דו-ממדי למערך חד ממדי:

  11. חיבור מטריצות – ללא הקצאה דינאמית 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; }

  12. חיבור מטריצות – עם הקצאה דינאמית 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; }

  13. /* 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; } חיבור מטריצות – ללא הקצאה דינאמית

  14. 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; } חיבור מטריצות – עם הקצאה דינאמית

  15. חיבור מטריצות – ללא/עם הקצאה דינאמית /* Check a matrix dimension*/ void CheckSize (int size) { if (size<0){ printf(“Matrix dimensions should be positive\n"); exit (1); } return; }

  16. חיבור מטריצות – ללא הקצאה דינאמית /* 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"); } }

  17. חיבור מטריצות – עם הקצאה דינאמית /* 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"); } }

  18. חיבור מטריצות – ללא הקצאה דינאמית /* 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; }

  19. חיבור מטריצות – עם הקצאה דינאמית /* 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; }

More Related