פורסם 2011 ביולי 1114 שנים לדוג'int* f(){int a[10]={1,2,3};return a;main(){int *b;b=f();scanf("%d",&b[0]);}שפת Cלמה אין פה שגיאה בזמן ריצה?המערך נמצא במחסנית של F לא? המחסנית נעלמת לאחר סיום הפונ' למה אין אקספשין?
פורסם 2011 ביולי 1114 שנים ערוך בבקשה את ההודעה ושים את הקוד בתוך תג קוד (כפתור שנראה כמו #). חוץ מזו, יעזור אם תציין (גם בכותרת) על איזו שפה אתה מדבר.ולשאלתך:נתחיל מזה שב-C אין exceptions. אם יש לך דריסת זכרון אז יכולה (אבל לא חייבת) לעוף שגיאה, תלוי אם המערכת מסוגלת לזהות את הדריסה (בד"כ דריסת מחסנית, כמו במקרה שכאן, לא ניתנת לזיהוי מיידי).המערך a לא "נעלם" אחרי היציאה מהפונקציה. המחסנית עובדת באופן הבא: יש מצביע שאומר איפה מתחילה המחסנית. כשאתה מגדיר משתנה, המצביע קטן וככה נוצר מקום עבור אותו משתנה (כלומר אם מצביע המחסנית הצביע על מקום 1000, והגדרת משתנה שתופס 4 בתים, אז מצביע המחסנית עכשיו יצביע למקום ,996, וזה למעשה יהיה גם המקום של אותו משתנה בזכרון).כשיוצאים מהפונקציה, הזכרון ש"הוקצה" עבור המשתנים המקומיים "משוחרר" ע"י כך שמצביע המחסנית פשוט מוגדל בחזרה.נניח לדוגמה שבכניסה לפונקציה, מצביע המחסנית הצביע על מקום 1000. כשאתה יוצר את a (שהוא מערך בגודל 4*10 בתים), מצביע המחסנית קטן ב-40, כלומר הוא עכשיו 960, והמקום של a בזכרון הוא בדיוק מקום 960. אם לדוגמה היית מגדיר עוד משתנה בשם x מטיפוס int, אז מצביע המחסנית היה יורד ל-956 ו-x היה יושב במקום הזה (a עדיין יושב ב-960).כשהפונקציה מסתיימת, הזכרון של המשתנים המקומיים "משוחרר" פשוט ע"י החזרת מצביע המחסנית למצבו ההתחלתי, לפני הכניסה לפונקציה - כלומר, למקום 1000. מה שהיה במקומות 956-1000 בזכרון לא נמחק, ומה שחוזר מהפונקציה הוא המצביע למקום ה-960 (שהיה המקום של a).מה שקורה בקוד שלך הוא ש-b עכשיו מצביע למקום 960 במחסנית, למרות שזה זכרון שלא "מוקצה". מצב כזה נקרא דריסת זכרון, והוא מאוד מסוכן - בעצם, b מצביע לזכרון שאינו "יציב", כי אף אחד לא מבטיח שלא ישנו אותו ע"י קריאה לפונקציה אחרת.(הערה: פישטתי כאן את המקרה, כי בעת קריאה לפונקציה יוצרים נכנסים עוד כל מיני פרטי מידע למחסנית, כמו המקום בקוד שממנו קראו לפונקציה, והפרמטרים המועברים לפונקציה)
פורסם 2011 ביולי 1114 שנים מחבר רגע אבל מערכת ההפעלה לא מזהה שיש מצביע לזיכרון שלא מוקצה?האם לדעתך התשובה הנכונה לשאלה מה יקרה בתוכנית זה : הקוד מאפשר הרצת קוד זדוני?
פורסם 2011 ביולי 1114 שנים מערכת ההפעלה יכולה לזהות אם יש מצביע למקום לא חוקי. כל המחסנית היא מקום חוקי, ולכן היא לא תעלה פה על בעיה.הקוד הספציפי הזה לא מאפשר הרצת קוד זדוני, כי בשום מקום לא מגיע קלט מחוץ לתכנית.
פורסם 2011 ביולי 1114 שנים מחבר שני דברים:1 אמרת שבסיום הפונ' הפוינטר שמצביע על המחסנית של הפונ' עולה בחזרה למעלה, כלומר מבחינת מע' ההפעלה אותו איזור בזיכרון הוא פנוי , למה גישה לאותו איזור בזיכרון לא מחזירה שגיאה על חריגה מהזיכרון? ואם לא מתי כן מוחזרת שגיאה על פניה לזיכרון שלא שייך לתוכנית?2 אם הפונק F הייתה קולטת מהמשתמש את הנתונים למערך האם אז כן היה ניתן להריץ קוד זדוני?תודה רבה על העזרה.
פורסם 2011 ביולי 1114 שנים מערכת ההפעלה לא מנהלת את המחסנית. זה באחריות התכנית בלבד.מערכת ההפעלה כן מנהלת הקצאות זכרון דינמיות (malloc/free).ולגבי 2, זה תלוי מאוד בקוד עצמו. יכול להיות קוד שאמנם יש בו חולשה, אבל לא ניתן לנצל אותה מסיבות אלו ואחרות (ההבדל בין vulnerable ו-exploitable).
פורסם 2011 ביולי 1114 שנים מחבר תודה steelmanx זה בידיוק זהאפשר לקבל דוג' מתי יש שגיאת זמן ריצה על פניה לכתובת זיכרון לא חוקית
פורסם 2011 ביולי 1214 שנים הדוגמה הכי פשוטה:int *p = NULL;*p = 5;זה יעבוד גם אם p מצביע למקום כלשהו שאינו ממופה לשום מקום בזכרון הפיזי של המחשב.
פורסם 2011 ביולי 1214 שנים מחבר מה ההבדל בין שני המקרים? בהנחה שהכתובת 5 היא כתובת חוקית שלא שמורה למ.ה.
פורסם 2011 ביולי 1214 שנים הבנת לא נכון את הקוד.הביטוי p = 5* אומר "שים את הערך 5 במקום בזכרון עליו מצביע p". המקום NULL הוא תמיד מקום לא חוקי.
פורסם 2011 ביולי 1214 שנים מחבר צודק. אם במקום להצביע לNULL היית נותן לו כתובת 5 לדוג'int *p=(int*)5;*p=4;למה פה כן מקבלים שגיאת זמן ריצה על Access violation ?
פורסם 2011 ביולי 1214 שנים כי גם 5 הוא ככל הנראה לא מקום חוקי. בכל רגע נתון, רוב הערכים האפשריים למצביע (ויש הרי 2 בחזקת 32 אפשרויות כאלו) לא ממופים לשום מקום בזכרון הפיזי. נסיון לגשת למקום כזה יגרור שגיאה.ספציפית, יש מקומות שלעולם לא יצביעו למקומות חוקיים (כמו NULL) ואני די בטוח ש-5 הוא גם אחד מהם.קרא עוד על זכרון וירטואלי.
פורסם 2011 ביולי 1214 שנים מחבר אני יודע מה זה זיכרון וירטואליאז מתי זיכרון כן ממופה? רק אם מכריזים עליו מראש? אז למה הכתובת של המערך בהודעה הראשונה כן ממופה? הרי בגמר הפונ' הזיכרון שהיא השתמשה בו משוחרר.
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.