שחרור זכרון בC...

  • פותח הנושא neko
  • פורסם בתאריך

אלדד28

New member
DTOR שומר עליך מפני טעויות.

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

erezsh

New member
ובו בזמן

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

אלדד28

New member
נו באמת

בדיוק כמו שאפשר לשכוח לעשות free ב-C, אפשר גם לשכוח לעשות delete או לנקות זכרון ב-ctor. הטיעון שלך לא רלוונטי. תוכניתן מסודר זוכר לנקות זכרון בין אם הוא עובד ב-C ובין אם הוא עובד ב-++C, ולהיפך.
 

voguemaster

New member
זה ממש לא נכון

בשפות כמו C ו- ++C אתה מנהל זיכרון. זה שיש dtor לא אומר שהזיכרון מנוקה אוטומטית כמו בג'אווה. אז נכון שלוקאלית עבור מחלקה אחת אתה מנקה את הזיכרון בצורה מרכזית ב-dtor אבל עדיין אתה מנהל זיכרון בכוחות עצמך. תראה, עיקרון מנחה בתכנות כשלומדים על פונקציות הוא שאם יש קטע קוד שמשתמשים בו בכמה מקומות בתוכנית לרוב הוא מתאים לפונקציה. עכשיו, עזוב אותך ממודולריות לרגע - העיקרון הוא לכתוב משהו פעם אחת ולהשתמש בו בכמה מקומות, מעין מקום מרכזי שכזה. אז ה-dtor הוא בדיוק דבר כזה: ניקוי זיכרון ומשאבים אחרים של המחלקה שלך. זה מקום מרכזי לביצוע הפעולות האלה אבל זה שזה מקום מרכזי לא אומר שאתה לא משחרר זיכרון לבד או מנהל אותו לבד. במשחקים לדוגמא אתה חייב אפילו לפעמים לכתוב מנהל זיכרון משל עצמך. אני לא מבין איך אתה יכול לבוא ולהגיד שב-++C לא מנהלים זיכרון לבד. כן, יש מצביעים חכמים והם עוזרים אבל זה לא משנה: א' - לא חייבים להשתמש בהם ולפעמים גם לא ממש צריך. ב' - עדיין אפילו אם מצביע חכם עוזר לך, עדיין יש ניהול זיכרון. עדיין אתה חייב לזכור לשחרר (או במקרה זה, במקום לזכור לשחרר פשוט לזכור להשתמש ב-SP) ואתה חייב להישמר משחרורים כפולים ועוד כל מיני צרות אחרות שמשחיתות את ה-HEAP.
 

selalerer

New member
גימיק, שמימיק!

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

erezsh

New member
משחק מילים מעולה. חשבת עליו לבד?

1. תודה 2. זו בדיוק הטענה. ואגב, מה הקשר כמה שורות הבנאי והמפרק?
 

eyalbd

New member
תן לי להסביר לך משהו

אם אתה כותב ב++C אתה חייב להשתמש ב-DTOR מסודר להקצאות משאבים. זה לא רק נוחות. הסיבה היא exception safety אתן לך דוגמא:
void function() { get_resource1(); get_resource2(); // Suppose this function throws..... // call_a_routine(); // <-------------------- free_resource2(); free_resource2(); }​
עכשיו נניח שהפונקציה באמצע זורקת exception. לתוכנית שלך יש leak. זה יכול להיות קובץ שנישאר פתוח, זיכרון, connection ועוד אלף ואחד סוגי משאבים שהתוכנית שלך צורכת. אם עוטפים יפה את המשאבים במחלקות פשוטות התוכנית שלך בטוחה יותר. אתן לך דוגמא טריויאלית:
struct C_File { C_File(const char* fname, const char* mode) { if ((fp = fopen(fname, mode) == 0) throw "Some Exception"; } ~C_File() { fclose(fp); } // dubious but just this example // operator FILE*() { return fp; } private: FILE* fp; };​
העטיפה הזאת לא עולה לך גרוש בביצועים ומקום, אבל דואגת לניקוי אוטומטי על כל חריגה בלתי צפויה. את זה אתה מקבל בזכות פונקצית DTOR שנקראת אוטומטית כל אימת שיוצאים מ scope, הן אם בגלל exception והן ביציאה נורמלית.
 

neko

New member
תגיד את זה למרצה של "סדנת תכנות

בשפת C", אני בטוח שהוא ישתכנע
 

voguemaster

New member
אני ממליץ בנוסף

במקום לעבוד עם גודל המערך בלולאה (להלן n או sizeX וכד') פשוט להקצות מצביע אחד יותר ולהכריז עליו שהוא NULL (עדיף שניים רציפים כדי שלא יווצר מצב שאם יש NULL באמצע המערך פתאום ואחריו איברים מוקצים כשנשחרר תהיה בעיה לשחרר אותם). ואז, כשרוצים לשחרר לא צריך לדעת את גודל המערך אלא רק לרוץ על המצביעים ולשחרר את אלו שהם לא NULL ולעצור ב-NULL (אפשר כפול אבל יש גם דרך אחרת למנוע מצב של NULL באמצע, ע"י אריתמתיקת פוינטרים פשוטה).
 

voguemaster

New member
בכלל לא

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