עבור לתוכן

מצביעים הקצאה דינאמית

Featured Replies

פורסם

שלום לכולם.

אני מבין הנושא הזה לא יפסיק לשגע אותי...

בכל מקרה נתקלתי בבעיה

נתון הקוד הבא (מדובר כמובן בשפת C/C++):

1. #include <stdio.h>

2. #include <stdlib.h>

3.void myfree(int *data){

4. free(data);

5. data = NULL;

}

6.int main(){

7. int *ptr = NULL;

8. ptr = (int *)malloc(sizeof(int));

9. myfree(ptr);

10. return 0;

}

(מיספרתי בשביל להקל על הסברים)

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

הבעיה:

כמו ששמתם לב כתבתי פונקציה myfree אשר משחררת את הזכרון ושמה את המצביע להיות NULL (למקרה שננסה לגשת אליו שוב נקבל SEGFAULT במקום לשנות ערך שנמצא בתא אליו מצביע המצביע), אבל בעת יציאה בהפונקציה PTR עדיין מבציע לתא שאותו קיבל בזמן הקצאת הזכרון. השאלה למה?

שאלה נוספת שארצה לשאול, בקשר לאותו קוד: נחליף את myfree ב free(ptr); ובין השורות 9 ו 10 נוסיף שורה נוספת: *ptr = 10; התוכנית לא תקרוס למה? אם ניתן לגשת לכתובת שהוקצאה גם אחרי שעשינו אליה FREE מה הטעם של FREE אז? האם הכתובת הזאת מסומנת אצל מערכת ההפעלה ככתובת פנויה ולמרות שתוכנית שלי יכולה לכתוב לשם ולקרוא משם קיים סיכוי השמערכת ההפעלה תשתמש בכתובת זו בתוכנית אחרת?

תודה רבה מראש.

פורסם

אתה צריך להבין איך מתנהל הזיכרון

ברגע שאתה משחרר זיכרון , אתה פשוט אומר למחשב שאין לך יותר שימוש באותו התא בזיכרון - הוא פנוי להובלות

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

זו הסיבה גם שכשאתה מוחק משהו מהמחשב הוא לא באמת נמחק ואתה יכול לשחזר אותו עם תוכנת שיחזור קבצים

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

פורסם
  • מחבר

כלומר בכל רגע נתון תא ששירחתי על ידי FREE (DELETE) יכול להיתפס על ידי תוכנה אחרת וכשאני אנסה לגשת אליו אני מקבל SEGFAULT?

ומה לגבי שינוי הכתובת של מצביע בתוך פונקציה?

פורסם

זה כבר תלוי מימוש. בגדול אם אתה מפתח על מערכת הפעלה 32 ביט אז אף תוכנה אחרת לא תיגע לך במרחב הזכרונות סתם ככה. הסיבה ש MYFREE לא משנה לך את PTR קשורה לאיך פרמטרים עוברים בין פונקציה, כדאי שתקרא על הנושא הזה כדאי להבין אותו לעומק יותר (הוא מאוד חשוב ולא קשור לבעיית זיכרון). עוד תלוי מימוש זה מה FREE עושה בשחרור זיכרון (יש סביבות פיתוח שבמצב DEBUG לא מאפשרות שחרור כפול ודואגות לאפס את הזיכרון ובמצב RELEASE מאפשרות וכו').

פורסם

כלומר בכל רגע נתון תא ששירחתי על ידי FREE (DELETE) יכול להיתפס על ידי תוכנה אחרת וכשאני אנסה לגשת אליו אני מקבל SEGFAULT?

כן

ומה לגבי שינוי הכתובת של מצביע בתוך פונקציה?

שאלה טובה, אני לא מאמין שהוא עושה FREE אוטומטית כל פעם שאתה משנה כתובת של מצביע מטעמי זמן ריצה

כנראה שהFREE מתבצע על הכתובות האלה ביציאה מהסקופ או בסגירת התוכנית.

פורסם

מה נסגר איתכם, אתם לא יודעים מתי להשתמש ב-quote ומתי ב-code? :)

הסיבה שבסוף התכנית המצביע עדיין לא NULL נובעת משגיאה שלך בפונקציה myfree.

פונקציות מקבלות תמיד עותק של הארגומנטים שמגיעים אליהן. הפונקציה הבאה:

void foo(int x)
{
x = x + 1;
}

לא תעשה כלום. למה? כי היא מקבלת עותק של x ומשנה אותו, אבל המשתנה המקורי שהגיע אליה נשאר אותו דבר.

על מנת לשנות את x צריך לעשות:

void foo(int *x)
{
*x = *x + 1;
}

באותו אופן, על מנת שהפונקציה שלך תוכל לאפס את data, היא צריכה לקבל משתנה מטיפוס **int.

פורסם
  • מחבר

חח אני השתשמתי ב QUOTE כי יותר נוח לראות את כל התוכנית ישר :)

בכל מקרה ככה חשבתי תודה רבה לכולם :)

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים