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

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

neko

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

אם הגדרתי מערך דו מימדי ע"י MALLOC כפול, האם מספיק לשחרר את הראשי, או שצריך ללכת ולשחרר כל מערך חד-מימדי בתוך המערך הדו-מימדי (כמו שהגדרתי)?
c = (int**)malloc(sizeX*sizeof(int*)); for (i=0; i<sizeX; i++) { c = (int*)malloc(sizeY*sizeof(int)); }

האם מספיק לכתוב בסוף התוכנית
FREE(C)​
?
 

erezsh

New member
למה שזה ישנה לו

אם זה מערך דו מימדי או מופע החבובות ? free משחרר את מה שאותר ע"י malloc, ואבוי אם ירגיש חופשי לעשות מעבר.
 

אלדד28

New member
ודאי שלא,

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

neko

New member
זאת אומרת שאם פונקציה הגדירה איזה

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

erezsh

New member
זה מה שזה אומר.

מה בדיוק לא אלגנטי ב:
for(i=0;i<n;i++) free(a); free(a);

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

זהיר

New member
אפשר, אבל מקטין גמישות

#define M 4 #define N 5 int *m = malloc(N*M*sizeof(int)); int **mm = malloc(N*sizeof(int*)); for (int i = 0; i < N; i++) { mm = m + i * M; } /* Use mm as a ragged array */ free(m); free(mm); /* Order independent */

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

selalerer

New member
C++ באה לפתור בדיוק בעיות מסוג זה.

אם זה לא חובה להשתמש בC, אני ממליץ בחום לעבור.
 

erezsh

New member
אבל גם אותם אתה צריך לכתוב

אז במקום לכתוב destruct() בסוף הפונקציה או משהו דומה, זה עושה את זה לבד? וואו, רק בשביל זה צריך לרוץ ישר ל-C++
 

selalerer

New member
תגיד לי אתה עושה צחוק?!

"גם אותם צריך לכתוב"???? אתה כותב מפרק פעם אחת עבור המחלקה, אפילו אם יש לך אלפי מופעים של המחלקה בתוכנית, אתה צריך לכתוב את קוד שחרור הזכרון רק פעם אחת! אתה רוצה להגיד לי שזה לא ייתרון?!
 

erezsh

New member
אם היתרון הגדול שלך

הוא להימנע מכתיבת שורה אחת על כל שימוש במערך (שייקח עשרות עד מאות שורות של קוד לטיפול), אז I rest my case. הבעיה עם כל השפות הגבוהות היא, שהן הפכו את המתכנתים לעצלנים. ומה רע בזה? שזה לא מתבטא רק בשורות הקוד, אלא גם באיכות שלו. כי אם לכתוב שורה נוספת זו טרחה משמעותית כ"כ, המתכנת יעדיף להחסיר אותה גם כשמדובר ביציבות הקוד, ואז מקבלים תוכנות שאין בהן בדיקות ל-Buffer Overflows כשהן קוראות נתונים מהרשת, ואז אנחנו מקבלים פירצת אבטחה. כי להוסיף את השורה הזאת שבודקת אורך היה טרחה משמעותית מדי.
 

אלדד28

New member
זה ממש לא קשור

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

erezsh

New member
זו לא המצאה מחדש של הגלגל

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

voguemaster

New member
בוא נגיד...

הקיום של ctor ו-dtor הוא לא הגימיק היחיד של ++C, אז באמת....
 

erezsh

New member
אז באמת! אבל selalerer כתב

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

voguemaster

New member
אבל זה לא שורה אחת

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

erezsh

New member
בדיוק על זה אני מדבר

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

gilad_no

New member
C++

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