שימוש בפונקציה realloc של C על מנת להקטין את המערך, הזיכרון מתפנה? - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

שימוש בפונקציה realloc של C על מנת להקטין את המערך, הזיכרון מתפנה?


MasterDK

Recommended Posts

שלום, לא מזמן למדנו מערך דינאמי הכי פשוט על MALLOC FREE REALLOC.

עכשיו עלי לממש מחסנית בעזרת מערך דינאמי.

כאשר אני משתמש ב realloc בשביל להגדיל את המערך הכל עובד יופי, האיבר האחרון נכנס לסוף או ל TOP של מחסנית.

עכשיו סביר להניח שעם אני אממש POP על ידי realloc ואתן לו גדול של מערך-1 האיבר האחרון ילך בדיוק כמו כמו במחסנית. השאלה היא מה יקרה לאותו תא ש"נאבד" האם הזכרון שלו יתפנה? או שעדיף לעתיק את כל המערך למערך חדש פחות האיבר האחרון לשחרר את המערך המקורי, להקצות לו מקום באחד פחות ולהתעיק מהעותק למקורי?

מצטער על השאלה לא מצאתי תשובה ב MANUAL של REALLOC.

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

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

באופן עקרוני זה בדיוק מה ש-realloc עושה: מקצה מקום חדש ומעתיקה את תוכן הזכרון, ומשחרר את המקום הישן.

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

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

מה זאת אומרת ידנית?

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

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

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

כן אני יודע שמערכת ההפעלה רק מסמנת שהוא פנוי.

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

זאת השאלה שלי.

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

להקטין את המערך אחרי כל פעולת POP לא יעיל גם אם REALLOC רק "משחרר" את התא האחרון.

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

בכל מקרה, כל הפעולות שקשורות להקצאה ושחרור של הם די כבדות. לכן, לשחרר ו/או להקצות של תא בודד בכל פעולת PUSH/POP לא כל כך יעיל, עדיף להקצות/ לשחרר בכפולות של 2.

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

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

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

yousux

תקרא שוב את השאלה שלי.. אני יודע מה REALLOC עושה, השאלה מה קורה לתאים האבודים כשהגודל משתנה לגדול לקטן יותר.

ktbnus

אני יודע שזה לא יעיל ואני לא הולך להשתמש בזה, הרעיון הוא ללמוד את ה ADT עצמו של מחסנית ולבצע אותו על ידי מערך דינאמי... זה מה שאני לומד המכללה..

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

כן..אכן זה משחרר את המקום.

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

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

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

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

למעשה גם במימוש סביר סוג כזה של פעולה עלול ליצור פרגמנטציה.

לסיכום:

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

עבור תוכנה ארוכת טווח שצריכה להיות איכותית - עדיף שתעבור לשיטה אחרת, או שתוודא שבסוג העבודה שלך עם המימוש שמולו אתה עובד, זה לא גורם בעיות.

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

הפונקצייה REALLOC היא פונקציה ALL IN ONE.

לדוגמא, אם אתה נותן לה גודל 0, הוא מבצעת FREE למצביע(ולא מקצה משהו באורך 0).

לא כדאי להשתמש בפונקציה הזו כדי שלא יקרו לך כל מיני דברים מוזרים בתוכנית שאתה לא יודע מה מקורם.

תשתמש רק ב FREE וMALLOC.

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

ארכיון

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

×
  • צור חדש...