ABA


"|C++| יש אפשרות להכריח משתנה בHeap להישאר בזכרון?"
גירסת הדפסה        
קבוצות דיון פיתוח, תיכנות ובניית אתרים נושא #10211 מנהל    סגן המנהל    מפקח   Winner    צל"ש   מומחה  
אשכול מספר 10211
Dotan  לחץ כאן להצגת דירוג המשתמש
חבר מתאריך 19.10.03
2849 הודעות, 2 פידבק
   02:00   31.12.10   
אל הפורום  
  |C++| יש אפשרות להכריח משתנה בHeap להישאר בזכרון?  
 
   שלום לכולם

מימשתי מחלקה כלשהי משל עצמי, של מטריצה.

אני מעוניין ליצור את כל המטריצות של סטטיות בלבד, הקצאה על הHeap בלבד.

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

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

תודה


                                שתף        
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד

  האשכול     מחבר     תאריך כתיבה     מספר  
  אם הבנתי את השאלה נכון - אז כן, ברגע שהיא סטטית ldan192  31.12.10 02:16 1
     בגלל השעה לא שמתי לב שרשמת על ה-Heap ldan192  31.12.10 02:46 2
         כן, התכוונתי ל-Stack, טעות שלי :} Dotan  31.12.10 11:27 4
             לא חייב אז רפרנס. ldan192  31.12.10 12:27 5
  משתנים סטטיים (שמוגדרים מחוץ לסקופ של מתודה, כולל main) Zippo  31.12.10 09:56 3
     אתה צודק בהכל חוץ מקבועים ומחרוזות שגם נמצאים ב DS Net_Boy  31.12.10 17:37 6
         אמנם זה משהו שלמדתי בקורס בשנה ראשונה Zippo  01.01.11 19:49 8
             כן המחרוזת הזאת ממש חלק מה DS Net_Boy  02.01.11 00:42 9
                 OK. תודה על התיקון! Zippo  02.01.11 03:19 11
                     תשובות Net_Boy  03.01.11 01:05 12
                         OK Zippo  03.01.11 08:30 13
  אין אופציה כזאת אם תסתכל באסמבלר על איך פונקציה מתבצעת Net_Boy  31.12.10 17:42 7
  הבנתי, תודה לכולם :) Dotan  02.01.11 01:33 10

       
ldan192 
חבר מתאריך 14.9.08
95119 הודעות
   02:16   31.12.10   
אל הפורום  
  1. אם הבנתי את השאלה נכון - אז כן, ברגע שהיא סטטית  
בתגובה להודעה מספר 0
 
היא נשמרת לאורך כל ריצת התוכנית (בדיוק כמו משתנה גלובאלי).
אז גם אפשר להחזיר אותה (by pointer/reference) בכל שלב בתוכנית...


בברכה,
עידן


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
ldan192 
חבר מתאריך 14.9.08
95119 הודעות
   02:46   31.12.10   
אל הפורום  
  2. בגלל השעה לא שמתי לב שרשמת על ה-Heap  
בתגובה להודעה מספר 1
 
ערכתי לאחרונה בתאריך 31.12.10 בשעה 02:56 בברכה, ldan192
 
אתה מתכוון ל-Stack, נכון?


בברכה,
עידן


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Dotan  לחץ כאן להצגת דירוג המשתמש
חבר מתאריך 19.10.03
2849 הודעות, 2 פידבק
   11:27   31.12.10   
אל הפורום  
  4. כן, התכוונתי ל-Stack, טעות שלי :}  
בתגובה להודעה מספר 2
 
  

ועוד משהו - אני לא יכול להוסיף משתנה REFERENCE כי אני מממש אופרטור ואני לא יכול להוסיף עוד פרמטרים לפונקציה..


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
ldan192 
חבר מתאריך 14.9.08
95119 הודעות
   12:27   31.12.10   
אל הפורום  
  5. לא חייב אז רפרנס.  
בתגובה להודעה מספר 4
 
נגיד:

int* func() {
static int num;
return &(num);
}

(הסוגריים בגלל שהפורום דופק את הטקסט בפנים...)

יהיה נכון בכל שלב


בברכה,
עידן


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Zippo 
חבר מתאריך 26.5.02
7921 הודעות
   09:56   31.12.10   
אל הפורום  
  3. משתנים סטטיים (שמוגדרים מחוץ לסקופ של מתודה, כולל main)  
בתגובה להודעה מספר 0
 
נמצאים על ה-Data segment
(אם אני לא טועה...)

משתנים מקומיים נמצאים ב-Stack

הקצאות דינמיות נמצאות ב- Heap

גלובליים נמצאים ב- Data segemnt

וקבועים\מחרוזות hard-coded נמצאים ב- Code segment

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

תחשוב מה הכי מתאים ונכון בתוכנית שלך, לפי הדיזיין שלך, ובזה תשתמש..


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Net_Boy  לחץ כאן להצגת דירוג המשתמש
חבר מתאריך 1.4.02
17151 הודעות, 1 פידבק
   17:37   31.12.10   
אל הפורום  
  6. אתה צודק בהכל חוץ מקבועים ומחרוזות שגם נמצאים ב DS  
בתגובה להודעה מספר 3
 
  


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Zippo 
חבר מתאריך 26.5.02
7921 הודעות
   19:49   01.01.11   
אל הפורום  
  8. אמנם זה משהו שלמדתי בקורס בשנה ראשונה  
בתגובה להודעה מספר 6
 
לפני יותר משנה, אבל אני די בטוח שמחרוזות hard-coded יושבות ב-CS.
כשאני כותב פקודה בסגנון:

String str = "some string";

אתה רוצה להגיד לי שהמחרוזת הזאת נמצאת ממש ב-DS?
זה חלק מהקוד... (טקסט\קוד)

עד כמה שאני זוכר, ה-DS מתחלק ל-2

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


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Net_Boy  לחץ כאן להצגת דירוג המשתמש
חבר מתאריך 1.4.02
17151 הודעות, 1 פידבק
   00:42   02.01.11   
אל הפורום  
  9. כן המחרוזת הזאת ממש חלק מה DS  
בתגובה להודעה מספר 8
 
  

int main()
{
char* pszHardCodedString = "Hello World";
return 0;
}

int main()
{
008D1350 push ebp
008D1351 mov ebp,esp
008D1353 sub esp,0CCh
008D1359 push ebx
008D135A push esi
008D135B push edi
008D135C lea edi,
008D1362 mov ecx,33h
008D1367 mov eax,0CCCCCCCCh
008D136C rep stos dword ptr es:
char* pszHardCodedString = "Hello World";
008D136E mov dword ptr ,offset string "Hello World" (8D573Ch)
return 0;
008D1375 xor eax,eax
}

שמתי את הdisassembly של הקוד מיד מתחת לפונקציה וכמו שאתה רואה,
הoffset של ה string נמצא באמת ב DATA SEGMENT.


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Zippo 
חבר מתאריך 26.5.02
7921 הודעות
   03:19   02.01.11   
אל הפורום  
  11. OK. תודה על התיקון!  
בתגובה להודעה מספר 9
 
למרות שאני לא ממש מבין מה אני רואה פה. i'll take your word for it.
אני יודע קצת אסמבלי, אבל זה לא נראה כמו X86...
מה זה:
0CCh , 33h , 0CCCCCCCCh , rep stos , dword ptr es: , dword ptr ,offset string "Hello World" (8D573Ch)
???

כל הביטויים האלה לא מוכרים לי בכלל...
ואיך אתה יודע שכתובת מסוימת שייכת לטווח הכתובת של הקוד\דאטא\סטאק\היפ?


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Net_Boy  לחץ כאן להצגת דירוג המשתמש
חבר מתאריך 1.4.02
17151 הודעות, 1 פידבק
   01:05   03.01.11   
אל הפורום  
  12. תשובות  
בתגובה להודעה מספר 11
 
   לגבי הדיסאסמבלי, זה פשוט רישום די נוח שתוכל לקשר כתובת למשתנה ולכן אתה רואה פתאום את המחרוזת "hello world" בפועל היא לא תופיע.
ולגבי הפקודות, זה אסמבלר של מעבדים מודרנים שעדיין מבוססים על X86 ודי אפשר להבין מה רוצים.


ולגבי איך אני יודע באיזה מקום נמצאת כתובת אז ככה:
אם היא ב CODE SEGMENT מן הסתם היינו רואים אותה אשכרה בקוד של הDISASSEMBLY.
אם היא ב STACK הייתה רואה את המשתנה מוגדר בפונקציה.
נותרנו עם DATA SEGMENT ו HEAP
אם זה בDATA SEGMENT
בMEMORY WATCH אתה יכול לראות את כל האיזור של ה DATA SEGMENT כי הוא די תחום ובלי קשר יש תוכנות שנותנות לך ממש לראות את כל המשתנים הסטטיים בזמן ריצה (אני חושב שזה אפשרי עם Process explorer)

ואם זה לא כל אחד מהמקרים האלו סביר להניח שזה ב HEAP
ושוב, זה גם איזור תחום שאפשר לראות דרך ה MEMORY WATCH

ואגב סימוכין מויקפידה למה שטענתי
http://en.wikipedia.org/wiki/Data_segment#Data


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Zippo 
חבר מתאריך 26.5.02
7921 הודעות
   08:30   03.01.11   
אל הפורום  
  13. OK  
בתגובה להודעה מספר 12
 
תודה רבה!


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Net_Boy  לחץ כאן להצגת דירוג המשתמש
חבר מתאריך 1.4.02
17151 הודעות, 1 פידבק
   17:42   31.12.10   
אל הפורום  
  7. אין אופציה כזאת אם תסתכל באסמבלר על איך פונקציה מתבצעת  
בתגובה להודעה מספר 0
 
   אתה תבין שנכנסים לך למחסנית הכתובת חזרה שממנה התבצעה הקריאה ואז המשתנים
ולכן אתה חייב לרוקן את כל המשתנים מהמחסנית כדי להגיע לכתובת חזרה.

יש לך כמה אופציות
1) תקצה דינאמית ותנהל את זה שאתה תמחק את המטריצות שאתה מקצה או שהמשתמש שביקש ימחק.
2) תקצה משתנים סטטיים שיהיו חיים לכל אורך התוכנית.
3) תיצור את המחלקה שלך כאובייקט סטטי (singleton) ואז תשמור את התוצאה כ MEMBER ותחזיר אותה ברפרנס.

תבדוק מה יותר מתאים לך לקוד ולעיצוב.


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Dotan  לחץ כאן להצגת דירוג המשתמש
חבר מתאריך 19.10.03
2849 הודעות, 2 פידבק
   01:33   02.01.11   
אל הפורום  
  10. הבנתי, תודה לכולם :)  
בתגובה להודעה מספר 0
 
  


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד

תגובה מהירה  למכתב מספר: 
 
___________________________________________________________________

___________________________________________________________________
למנהלים:  נעל | תייק בארכיון | מחק | העבר לפורום אחר | מחק תגובות | עגן אשכול
       



© כל הזכויות שמורות ל-רוטר.נט בע"מ rotter.net