שאלה קשה מאוד...

ihovav

New member
לגבי "איך עובד מאלוק"

מאלוק קורא לפונקציה של מערכת ההפעלה - אני מניח שבמקרה של ווינדוז הוא עושה ישר COMMIT ולא RESERVE ואז COMMIT. חשוב להבין שרק מערכת ההפעלה יכולה לגשת למשאבי מערכת, וזה כולל קבצים, זיכרון, COMים ועוד - אין כזה מצב שקומפיילר יגש בעצמו למשאבים מבלי לבקש ממערכת ההפעלה - זה פשוט לא קיים...
 

Scipio

New member
טוב גם אתה לא מדייק

הקצאת זיכרון יכול להעשות ממערכת ההפעלה ויכולה להעשות מהאפליקציה למשל : 1. בתור אפליקציה אתה מקצה בלוק זיכרון גלובלי ואז מנהל אותו בעצמך כך שלמעשה כל ה MALLOCS הם פנימים מלבד הראשון (וגם אותו אפשר להקצות בצורה סטטית. בקיצור הקצאת זיכרון זה עניין של ספריות אשר יכול להיות מממומש במערכת הפעלה / בקופמפלייר (בספריות הסטנדרטיות הנלוות אליו) או ברמת המשתמש. ישנם אין ספור מימושים של הקצאות זיכרון ולא כולם חייבים להכיל OVERHEAD של גודל.
 

ihovav

New member
זו התחכמות

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

Scipio

New member
בשביל הדיון אני יחלוק

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

osnat77

New member
לא להתווכח עם חובב!!!

ברור שאתה סתם מתחכם! חובב אומר וחובב יודע! 3 קריאות הידד לחובב! (חובב:
)
 

dudil

New member
שחכת לציין שהם ביקשו ממך לממש את

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

yair24

Member
../images/Emo13.gif אני רואה שגם אתה היית שם...

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

אלדד26

New member
שתי הערות

1. הגודל לא יכול להיות בשני הבתים הראשונים, כי אז לא הייתה עובדת כל האריתמטיקה הבסיסית של המצביעים. אם כבר, אפשר לשמור את הגודל לפני הבלוק, ואז ה - free ייגש לשם ויפנה את הזיכרון. 2. אם המשתמש ביקש (malloc(40, אז הוא מתכוון ל - 40. הוא לא רוצה 38, אלא 40. בפועל יוקצו (אולי, תלוי במימוש של malloc) עוד בתים כדי לשמור את גודל הבלוק. מימוש אחר הוא שמירה של טבלאות בצד, כמו שכבר הוזכר קודם. טבלאות בצד מאפשרות ניהול יותר מהיר ויעיל של הקצאת בלוקים חדשים (בדיקה אם יש מקום פנוי בדף וכו´), אבל מצד שני, ה - free יהיה יותר איטי כי צריך לחפש ברשימה. למרות זאת, אני חושב שאין מנוס משימוש בטבלאות ניהול בלוקים. מצורף לינק להסבר נוסף ולמימוש אפשרי של האלגוריתמים מאחורי malloc.
 

TZURYOAV

New member
אתה מקשקש שטויות כי אתה לא מכיר את

השאלה,אני מכיר לכן עניתי לו מה שעניתי. הוא החסיר פרטים אבל בעקרון אתה צריך לממש את MALLOC ו FREE עכשיו כשמשתמש מבקש הקצאה של 40 בתים אתה מקצה לו 40 בתים+ SIZEOF(INT) ואז ב4 בתים הראשונים את מאחסן את גודל ההקצאה ומחזיר לו פוינטר ל בית ה 4 כי 0-3 תפוסים. מבין? יואבי-העצבני
 

voguemaster

New member
זאת הדרך הפשוטה והלא-יעילה

לנהל דפי זיכרון. השיטה המקובלת היום בכל ה-UNIXים שמכבדים את עצמם (ומגרסאת קרנל 2.4 לינוקס גם עשתה כמה צעדים לכיוון) היא ע"י טבלאות. ד"א, לא שללינוקס לא היו טבלאות גם קודם, אבל האלגוריתמים שמנהלים דפי זיכרון "מלוכלכים" ועוד כל מיני דברים, עברו שינויים. בכל אופן, אני די בספק אם עדיין יש מערכות הפעלה בנות דורנו שמשתמשות ביישום שלך ל-MALLOC ו-FREE. אלי
 

yair24

Member
ידוע לך אולי..

באיזה שיטה משתמש MALLOC של TC של DOS? יאיר
 

yair24

Member
אל תתעצבן יואבי...

הרי אתה לוחם חופש!! ממציא!! זוכר?
עכשיו תגיד לי משהו מה זה הP! שרשמת בנושא של התשובה שלמעלה? יאיר
 

אלדד26

New member
לא אדרדר את הדיון לרמה שלך.

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

yair24

Member
דוקא כן יכול להיות...

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

אלדד26

New member
לא, יאיר -

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

yair24

Member
אה נכון צודק לא שמתי לב...

התשובה של ה38 בתים באמת לא נשמעת הגיונית כל כך אבל תשובה של הקצאה של מקום למערך פלוס עוד מקום (אני אומר בכוונה "מקום", ולא בתים כי בבתים זה צריך להיות עוד 4 או 2 או השד יודע כמה, תלוי במערכת) אחד בשביל הגודל שלו נשמעת טוב... אבל רגע, איפה בעצם נשמרות הטבלאות האלה? והאם הכוונה לHASH TABLES? יאיר
 

gilad_no

New member
גם אתה לא הבנת אלדד

מה שיואב ניסה להסביר זה כך: אם משתמש מבקש הקצאה של 40 בתים אז מוקצים לך בעצם 44 בתים (או 42, או 48 - תלוי במערכת ההפעלה). הפונקציה שמקצה נראית כך:
void* malloc(int nSize) { byte *pVoid=allocate_from_system(nSize+sizeof(int)); *((int*)pVoid)=nSize; return (void*)(pVoid+sizeof(int)); } void free(void* pVoid) { byte *pByte=(byte*)pVoid; pByte-=sizeof(int); free_from_system(pByte,*((int*)pByte)); }​
וזה בצורה סכמטית. בחלונות, ניתן לממש מספר שיטות. אני לא כ"כ זוכר את הפונקציות, אבל יש פונקצית מערכת שמקצה בלוק ליישום והוא אחראי מצידו לכל ההקצאות הקטנות שהוא עושה. בדרך כלל זה ממומש ע"י המהדר (הכוונה ע"י ספריות שמקושרות לאפליקציה בזמן ההידור) אבל ניתן גם לתת לחלונות לנהל את זה. אין לי שום מידע מי עושה עבודה יותר טובה: מערכת ההפעלה או הספריות המקושרות ליישום, אבל אם למישהו יש רעיון טוב הוא גם יכול לממש את זה לבד: להקצות בתחילת התכנית בלוק גדול ולנהל בתוכו את כל ההקצאות. בסיום התכנית, צריך רק לשחרר את הבלוק וכך לא צריך לדאוג לנזילות זיכרון. ובנוסף יש לי שאלה: חלונות 2000 לא כ"כ רגישה לנזילות זיכרון של יישומים כמו חלונות 98. האם היא מקצה לכל יישום זיכרון עם הרצתו ומשחררת את הזיכרון בסיום ההרצה? אשמח אם יש מישהו שיודע כיצד זה עובד
 
למעלה