C++/זיכרון דינמי: הבדלים בין גרסאות בדף

תוכן שנמחק תוכן שנוסף
Ybungalobill (שיחה | תרומות)
Ybungalobill (שיחה | תרומות)
אין תקציר עריכה
שורה 1:
{{C++‎}}
== מהי הקצאת זיכרון דינמית ==
;הקצאת זיכרון דינמית: היא פעולה של הקצאת זיכרון בעתבזמן הרצתריצת התוכנה. פעולה זו מבוצעת בדרך כלל כאשר גודל הזיכרון הנדרש אינו ידוע מראש לפני הרצת התוכנה ויתברר רק לאחר קבלת קלט מהמשתמש, קריאת תוכן של קובץ כלשהו וכדומה.
 
== כליםהקצאה להקצאתושחרור זיכרון דינאמית ב־C++‎ ==
מאחר ובשפת C++‎ יש תמיכה מלאה בכל הספריות הסטנדרטיות של C,
נתןניתן להשתמש בפונקציות של C כגון malloc ו-free, אך הדבר אינו מומלץ,
כיוון שב־C++‎ יש כלים מתקדמיםמיוחדים יותרלמטרה זו התומכים במחלקות (כלומר מריצות את הבנאים ומפרקים, למד בהמשך).
 
ב־C++‎ מקצים זיכרון באופן דינמי באמצעות אופרטור new.
ב־C++‎ מקצים ומשחררים זיכרון באופן דינמי באמצעות האופרטורים new ו-delete עבור משתנים בודדים ו-[]new ו-[]delete עבור מערכים.
ישנה צורה בשפת C++‎ המאפשרת הקצאה דינמית של משתנה בודד וכן מערך.
 
=== משתנה בודד ===
להקצאת זיכרון עבור משתנה בודד נשתמש באופרטור new כאשר אחריו נרשום את סוג המשתנה. אופרטור זה מחזיר מצביע למשתנה זה, לכן עלינו לשמור אותו כדי להשתמש בו. דוגמה:
*תקציר:
<div style="text-aligndirection:left; direction:ltr;"><pre>typesource *variablelang=new type;</pre></div"cpp">
int *myintptr = new int;
* הסבר:
cin >> *ptr;
הקצאה ל־variable מסוג מצביע ל־type מקום בזיכרון מסוג של type.
/*...*/
*דוגמא:
delete arrayptr;
<div align="left" dir="ltr" >
</presource></div>
<pre>
כך נקצה משתנה מטיפוס int בזיכרון הדינמי ונשמור את המצביע עליו למשתנה ptr. לאחר השימוש בזיכרון זה נשחרר אותו ע"י האופרטור delete.
int *new_integer=new int;// הקצאה דינמית של מספר שלם.
 
</pre></div>
=== מערך ===
להקצאת מערך בזיכרון הדימני נשתמש באופטור []new. כדי להקצות מערך, בדומה להקצאת משתנה בודד, עלינו לציין את הטיפוס של האיברים במערך ובנוסף את גודל המערך. המצביע שיוחזר ע"י האופרטור []new יצביע לתחילת המערך ובו נשתמש כדי לשחרר את הזיכרון באמצעות []delete בתום השימוש. הנה קטע קוד לדוגמה אשר קולט מהמשתמש את גודל המערך ואת איבריו:
*תקציר:
<div style="text-aligndirection:left; direction:ltr;"><pre>typesource *arraylang=new type[array_length];</pre></div"cpp">
int *array=new int[length];
*הסבר:
cin >> length;
הקצאה ל־array מסוג מצביע ל־type מקום בזיכרו שהוא מערך של ערכים של type באורך array_length.
*דוגמא:
<div align="left" dir="ltr" >
<pre>
const short int arr_size = 10;
int* new_array = new int[arr_size];// הקצאה דינמית של מערך של 10 מספרים שלמים.
</pre></div>
 
int *myarrayarray = new int[length];
== שחרור הזיכרון שהוקצה ==
for(int i = 0; i < length; i++)
על מנת לשחרר את הזיכרון שהוקצה נתן להשתמש באופרטור delete.
cin >> array[i];
*תקציר:
/*...*/
 
<div style="text-align:left; direction:ltr;"><pre>
delete variable;
delete[] array;
</presource></div>
שימו לב שבזכות ההקצאה הדינמית, אנו יכולים לציין את גודל המערך לא בהכרח כקבוע, כך נוכל לקבוע בזמן ריצת התוכנית את גודל הזיכרון המוקצה.
 
*הסבר:
variable הינו משתנה בודד שהוקצה באמצעות new.
 
array הוא מערך שהוקצה באמצעות new[].
חשוב לציין כי במקרה של מערך חייבים להוסיף סוגריים מרובעות הנ"ל.
תוצאה של
 
<div style="text-align:left; direction:ltr;"><pre>
int *array=new int[length];
delete array;
</pre></div>
'''אינה מוגדרת'''.
 
*דוגמא:
 
<div style="text-align:left; direction:ltr;"><pre>
// משתנה בודד
int *myint=new int;
// פעולות נוספות.
delete myint;
 
// מערך
int *myarray=new int[length];
// פעולות נוספות
delete[] myarray;
 
== פרטים על האופרטורים new ו-delete ==
</pre></div>
 
* כאשר אין אפשרות להקצות את הזיכרון הנדרש האופרטור new יחזיר מצביע 0 (NULL) או יזרוק חריגה bad_alloc בהתאם להגדרות המהדר.
* זיכרון שהוקצה ע"י new צריך לשחרר ע"י delete וזיכרון שהוקצה ע"י []new צריך לשחרר ע"י []delete, אחרת אופן פעולת התוכנית לא מוגדר והיא עלולה לקרוס.
* אם נשתמש בפונקציות של C להקצות זיכרון, אין לשחרר אותו באמצעות אופרטורי ++C, ולהיפך.
* על אף שלא ניתנת הודעת שגיאה על אי שחרור זיכרון שהוקצה ומערכת ההפעלה תשחרר, בדרך כלל, את הזיכרון באופן אוטומטי בעת סיום פעולת התוכנית, רצוי לשחרר את הזיכרון ע"י delete ישירות לאחר סוף השימוש בו. הסיבה לכך היא מניעת דליפת זיכרון וצורך להפעיל את המפרקים של המחלקות (למדו בהמשך).
* נוכל לציין את גודל הזיכרון המוקצה למערך שווה ל-0. דבר זה לא נחשב לשגיאה. זיכרו כי נצטרך לשחרר זיכרון זה כמו כל זיכרון אחר, הסיבה לכך היא המבנה של הערימה.
 
== שינוי גודל הזיכרון שהוקצה ==