שאלה הבנה לגבי הקצאת זכרון בC++ - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

שאלה הבנה לגבי הקצאת זכרון בC++


amirxbox

Recommended Posts

אני לומד בבן גוריון וכמעט ולא נגעתי ב C++ (יודע C וJAVA).

אם הקצאה בSTACK היא בזמן קומפילציה וצריכה גודל מדויק של מבנה נתונים לא הבנתי מדוע קטע הקוד הבא תקין?

 
int main(){
ifstream in("file.txt");
string s ,line;
while(getline(in,line))
s+=line + "\n";

cout << s
}

אני ממש לא מבין איך S גדל וגדל והוא על הSTACK ללא NEW.

ב JAVA זה מאוד ברור כי כל STRING הוא על ה HEAP.

ד"א הקוד מהספר לחשוב ב C++ שהוא חינמי ברשת.

קישור לתוכן
שתף באתרים אחרים

ה destructor של string אחראי לנקות את הזכרון שהאובייקט הקצה. האובייקט עצמו מוקצה על ה stack אבל זה לא מונע ממנו (מהמימוש של המחלקה string) להקצות דינמית אובייקטים (כמו מערך תווים) על ה heap ולהחזיק מצביע אליהם.

קישור לתוכן
שתף באתרים אחרים

הוא יצביע על מה שנקרא ערך לא מוגדר.

יכול מאוד להיות שבמקרה לחלוטין, מיד לאחר קטע הקוד הזה, המחרוזת תהיה עדיין תקינה.

אבל על פי ההגדרה, ההתנהגות בפניה למחרוזת מחוץ לקטע הזה היא לא מוגדרת.

קישור לתוכן
שתף באתרים אחרים

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

קישור לתוכן
שתף באתרים אחרים

הנה באג:



{
string *ps
{
string s;
s = "abc";
ps = &s;
}

*ps = "def"; // this is a bug!!!
}

צורה דומה של הבאג שקצת יותר נפוצה אצל אנשים שלא יודעים C++ כמו שצריך:


string* get_name()
{
string name = "Zelig";
return &name; // BUG! (dangling reference)
}

קישור לתוכן
שתף באתרים אחרים

כן זה ברור, אבל יכולות לצוץ הרבה בעיות למשל:


{
string s("amir");
string* st = &s;
s=null;
return st;
}

קשה מאוד להבין מה קורה בכל מצב מוזר כזה, למי שרגיל לJAVA .

תודה רבה על התשובות

אגב, null (המילה השמורה) לא קיימת ב c++ . קיים בספריות של c מאקרו NULL ששווה אפס אבל אין מילה שמורה כזו בשפה. אולי אתה מערבב קצת עם java.

קישור לתוכן
שתף באתרים אחרים

תשתמש ב-NULL.

קבצי H שבאים עם הקומפיילר אמורים להגדיר את NULL נכון בהתאם לאיך שאתה מקמפל כרגע, ולכן NULL עובד ב-99.99% מהמקרים.

ב-C++ אתה יכול להשתמש ב-0 (למעשה גם ב-C) אבל אני ממליץ תמיד להשתמש ב-NULL על מנת להפריד עבודה עם מצביעים לבין מספרים.

קישור לתוכן
שתף באתרים אחרים

ארכיון

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

×
  • צור חדש...