עבור לתוכן

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

Featured Replies

פורסם

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

זיהיתי כי הבעיה היא ככל הנראה חוסר שליטה והבנה בנושא המצביעים.

לאחר מעבר וחזרה על החומר, הגעתי שוב לנושא ההקצה הדינמית.

כאן, עלו בפני מספר שאלות:

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

עוד דבר שלא לגמרי ברור לי-אם למשל אני רוצה להריץ תכנית מאין זו:


#include <stdio.h>
#include <stdlib.h>
int main()
{


int *numbers = (int *)malloc( 1 * sizeof(int) );
if(numbers == NULL)
printf("Error: could not allocate memory!\n");



int a=3;
&a=numbers;
printf("\n%d", a);
free(numbers);








fflush(stdin);
getchar();


return 0;


}

בה אני מכריז על משתנה מסוג int בשם a, ורוצה להשים את הכתובת שהוקצאה לי למשתנה הזה. מדוע אין באפשרותי לעשות כן?

נערך על-ידי Neus

פורסם

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

הביטוי a& הוא "לקריאה בלבד" - אי אפשר לשים בתוכו ערכים. הוא פשוט מכיל את הכתובת של המשתנה a בזכרון.

נ.ב. מומלץ שתציין (בכותרת) את השפה עליה אתה מדבר.

נערך על-ידי שניצל

פורסם
  • מחבר

אוקיי, אני חושב שהבנתי:)

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

פורסם

כמובן. אפשר להגדיר מצביע למצביע באמצעות שתי כוכביות.

פורסם
  • מחבר

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

פורסם

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

הכל תלוי שימוש ומימוש.

אתה מקצה מקום על הערימה עם malloc ומחזיק מצביע מקומי במחסנית.

פורסם
  • מחבר

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

פורסם

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

פורסם

בסופו של דבר על כל malloc צריך להיות free - אחד לאחד.

פורסם
  • מחבר

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

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

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

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

פורסם

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

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

נערך על-ידי שניצל

פורסם
  • מחבר

תראה, המחסנית היחידה שאני מכיר היא המחסנית שלי מהM-16 בשירות הצבאי. כשאתה מדבר על מחסנית, אתה מתכוון לזיכרון הRAM? כשאתה מדבר על פונקציות, אתה למעשה מתכוון לפונקציות כגון scanf, printf וכד'?

פורסם

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

אני בטוח שתמצא תשובות טובות מאוד ב-stackoverflow.

פורסם

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

פורסם
  • מחבר

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

[COLOR=#993333]char[/COLOR] my_string_2[COLOR=#009900][[/COLOR][COLOR=#009900]][/COLOR] [COLOR=#339933]=[/COLOR] [COLOR=#FF0000]"wiki"[/COLOR][COLOR=#339933];[/COLOR]

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

נערך על-ידי Neus

ארכיון

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

דיונים חדשים