Presentation is loading. Please wait.

Presentation is loading. Please wait.

מבוא למדעי המחשב תרגול 12 – הקצאת זיכרון דינאמית שעת קבלה : יום שני 11:00-12:00 דוא " ל :

Similar presentations


Presentation on theme: "מבוא למדעי המחשב תרגול 12 – הקצאת זיכרון דינאמית שעת קבלה : יום שני 11:00-12:00 דוא " ל :"— Presentation transcript:

1 מבוא למדעי המחשב תרגול 12 – הקצאת זיכרון דינאמית שעת קבלה : יום שני 11:00-12:00 דוא " ל : keren@eli-wigs.comkeren@eli-wigs.com

2 מצביעים-תזכורת מהשיעור הקודם  מצביע הוא משתנה שמכיל כתובת זיכרון.  הצהרה על מצביע : שם _ המצביע * טיפוס למשל :int *ptr; ptr הוא מצביע שיוכל להכיל כתובת של משתנה מטיפוס int.  האופרטור &: שם _ משתנה & = כתובת הזיכרון של המשתנה. למשל : x& = הכתובת של x.  לאחר ההצהרה על מצביע ניתן לתת לו ערך – כתובת זיכרון. ptr=&x; הערך של המצביע ptr הוא כתובת הזיכרון של המשתנה x. או במילים אחרות ptr מצביע על x.

3  האופרטור *: שם _ מצביע * = המשתנה עליו מצביעים. בדוגמה הקודמת ptr הצביע על x, כלומר x= *ptr. ולכן הפקודות הבאות שקולות : x=5; *ptr=5;

4 מצביעים ופונקציות  על מנת לשנות את ערכי המשתנים של הפונקציה הקוראת, נעביר לפונקציה את כתובות המשתנים ולא את ערכיהם. למשל : int num1=10,num2=12; func(&num1,&num2); הפונקציה func מקבלת שתי כתובות של משתנים, ולכן המשתנים המועברים שלה יהיו מצביעים. למשל : void func(int *a,int *b) a הוא מצביע שמקבל את הכתובת של num1, b הוא מצביע שמקבל את הכתובת של num2. אם נכתוב למשל : *a=14 אז הערך של num1 יהיה 14.

5 מערכים ומצביעים  שם המערך הוא מצביע לאיבר הראשון במערך. למשל : char a[5]; a הוא מצביע, ערכו הוא הכתובת של a[0]. כלומר, a[0] שקול ל *a כמו כן, a[3] שקול ל *(a+3)  קידום מצביע : אם ערכו של ptr הוא 2000, והמשתנה עליו מצביע ptr הוא מטיפוס float שתופס 4 בתים, אז הערך של ptr++ הוא הכתובת 2004.

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

7 הפונקציה malloc  תפקיד הפונקציה malloc הוא להקצות ברצף מקום בזיכרון למשתנים חדשים תוך כדי ריצת התכנית.  הפונקציה מוגדרת בספרייה stdlib.h ולכן על מנת להשתמש בה יש לכלול ספרייה זו. כלומר, בתחילת התוכנית נרשום : #include  הפונקציה מקבלת את מספר הבתים שנרצה להקצות, מחפשת בזיכרון מקום פנוי ( רצוף ) בגודל המבוקש, ומחזירה את כתובת הזיכרון של המקום הפנוי, או NULL אם אין מקום פנוי.  לערך המוחזר מהפונקציה נעשה הסבה לטיפוס איתו אנו רוצים לעבוד.

8  מספר הבתים שנרצה להקצות הוא מספר המשתנים מטיפוס מסוים כפול מספר הבתים שתופס משתנה זה בזיכרון.  כאמור, מספר זה יכול להשתנות ממערכת למערכת, ולכן נוכל להיעזר בפונקציה sizeof(type) שמחזירה את מספר הבתים שתופס משתנה מטיפוס זה במערכת עליה אנו עובדים.  למשל, אם נרצה להקצות 10 משתנים מטיפוס int נרשום : malloc(10*sizeof(int))

9  הקריאה לפונקציה malloc בדרך כלל תיראה כך : pointer=(type *)malloc(n*sizeof(type))  למשל : אם נרצה להקצות 5 משתנים מטיפוס int int *ptr; ptr=(int*)malloc(5*sizeof(int))  עכשיו המצביע ptr מצביע לכתובת האיבר הראשון במערך זה, וניתן להשתמש בו כמו בכל מערך אחר. הסבת טיפוס הערך המוחזר לטיפוס הרצוי מס ' המשתניםמס ' הבתים שתופס משתנה מהטיפוס הרצוי

10  לאחר כל הקצאת זיכרון דינאמית עלינו לבדוק אם ההקצאה הסתיימה בהצלחה.  אם הפונקציה malloc לא מצאה מקום פנוי בזיכרון היא מחזירה את הערך NULL. ולכן יש לבדוק האם הערך המוחזר הוא NULL, אם כן נדפיס הודעת שגיאה.  למשל, בדוגמה הקודמת : if (ptr==NULL) { printf ( “ could not allocate memory \n ” ); return; }

11 הפונקציה free  כשאנו מקצים זיכרון בהקצאה סטטית, הזיכרון מתפנה אוטומטית בסיום פונקציה.  בהקצאה דינאמית עלינו לדאוג לשחרר את הזיכרון כאשר אין לנו צורך בו יותר. אחרת, הזיכרון יכול להתמלא עד שלא יישאר בו מקום.  שחרור הזיכרון נעשה על ידי שימוש בפונקציה free שמוגדרת גם היא בספרייה stdlib.h, באופן הבא : free(ptr); כאשר ptr הוא מצביע שמכיל את כתובת תחילת הזיכרון שהוקצה באופן דינאמי.  אם הקצנו זיכרון באופן דינאמי בתוך פונקציה, ואנו רוצים להשתמש בזיכרון זה גם לאחר שהפונקציה מסתיימת, אז נעביר את הכתובת של הזיכרון שהוקצה למצביע אחר שמוגדר בפונקציה הקוראת. כשנסיים להשתמש בזיכרון זה נשחרר אותו בעזרת המצביע שקיבל את כתובת תחילת הזיכרון בפונקציה הקוראת.

12 תרגיל  כתוב תכנית שקולטת מהמשתמש את גודל המערך, מכניסה לתוכו מספרים שלמים, ומדפיסה את המספר הגדול ביותר.

13 תרגיל #include void main() } int num,*ptr,i,max; printf (" how many numbers would you like to have? \n"); scanf ("%d",&num); ptr=(int*)malloc(num*sizeof(int)); if (ptr==NULL) } printf (" could not allocate memory \n"); return; { printf ("enter %d integers",num); for (i=0;i<num;i++) scanf("%d",&ptr[i]); max=ptr[0]; for (i=1;i<num;i++) if (ptr[i]>max) max=ptr[i]; printf (" %d is the maximum ",max); free(ptr); { קליטת גודל המערך מהמשתמש המצביע ptr מקבל את כתובת תחילת המערך שהוקצה ע " י הפונקציה malloc. כאשר אברי המערך יהיו מטיפוס int בדיקת הערך שהוחזר ע " י malloc התייחסות למצביע ptr כשם של מערך הכללת הספרייה stdlib.h שחרור קטע הזיכרון עליו מצביע ptr

14 תרגיל  כתבו תכנית שמקבלת כקלט סדרת מספרים שלמים וממיינת אותם. המשתמש יכניס כקלט את מספר האברים בסדרה.

15 #include void swap(int *a,int *b); void sort(int *a,int n); void main() } int i,size,*array; printf ("enter the number of integers\n"); scanf ("%d",&size); array=(int*)malloc(size*sizeof(int)); if (array==NULL) } printf ("could not allocate memory\n"); return; { printf ("enter %d integers",size); for (i=0;i<size;i++) } scanf("%d",&array[i]); sort(array,i+1); { printf ("the sorted array is:\n"); for (i=0;i<size;i++) printf ("%d ",array[i]); free(array); { קליטת מספר האברים בסדרה הקצאה דינאמית למערך החדש בדיקה האם ההקצאה הסתיימה בהצלחה קליטת ערכים למערך החדש קריאה לפונקציה שתמיין את המערך הדפסת המערך הממויין

16 void swap(int *a,int *b) { int temp=*a; *a=*b; *b=temp; } void sort(int *a,int n) { int i; for (i=n-1;i>0;i--) if (a[i]<a[i-1]) swap(&a[i],&a[i-1]); } הפונקציה sort מקבלת n אברים ראשונים של המערך, בודקת עבור כל זוג אברים עוקבים אם האיבר קטן מזה שלפניו. אם כן, שולחת אברים אלו לפונקציה swap שמחליפה ביניהם

17 סיכום  על מנת להקצות זיכרון במהלך ריצת התכנית נשתמש בפונקציה malloc המוגדרת בספרייה stdlib.h (* טיפוס )= מצביע malloc* מספר _ המשתנים )sizeof((( טיפוס ;  לאחר ההקצאה נבדוק אם היא הסתיימה בהצלחה : if ( מצביע ==NULL) …  ניתן להתייחס למצביע כאל מערך.  כשנסיים את השימוש במצביע נשחרר אותו : free( מצביע );


Download ppt "מבוא למדעי המחשב תרגול 12 – הקצאת זיכרון דינאמית שעת קבלה : יום שני 11:00-12:00 דוא " ל :"

Similar presentations


Ads by Google