הקצאה באמצעות calloc()
חלק מהיחידה לוגיקה וזרימת תוכנית במסלול ה-C של Coddy. שיעור 36 מתוך 63.
בעוד ש־malloc() היא הפונקציה הנפוצה ביותר להקצאת זיכרון דינמית, C מספקת חלופה שימושית נוספת: calloc(). הפונקציה calloc(), ששמה הוא קיצור של "contiguous allocation" (הקצאה רציפה), מציעה דרך נוחה להקצות זיכרון למערכים, עם יתרון חשוב נוסף.
בניגוד ל־malloc(), שמקבלת ארגומנט יחיד (מספר הבתים הכולל), calloc() מקבלת שני ארגומנטים: מספר האיברים שברצונך להקצות והגודל של כל איבר. כך השימוש בה אינטואיטיבי במיוחד בעבודה עם מערכים. לדוגמה:
#include <stdlib.h>
// הקצו מקום ל-5 מספרים שלמים באמצעות calloc()
int *arr = (int*)calloc(5, sizeof(int));
// זה שקול ל: malloc(5 * sizeof(int))היתרון המרכזי של calloc() הוא שהוא מאתחל אוטומטית את כל הזיכרון שהוקצה לאפס. כשמשתמשים ב־malloc(), הזיכרון שהוקצה מכיל את הערכים האקראיים שאוחסנו בו קודם לכן, אבל calloc() מבטיח שכל בית יוגדר לאפס. פירוש הדבר הוא שכל המספרים השלמים יהיו 0, כל המספרים העשרוניים יהיו 0.0, וכל המצביעים יהיו NULL.
בדומה ל־malloc(), גם calloc() מחזירה מצביע לזיכרון שהוקצה או NULL אם ההקצאה נכשלת, לכן תמיד כדאי לבדוק אם ההקצאה נכשלה ולזכור לשחרר את הזיכרון באמצעות free() כשתסיים להשתמש בו.
אתגר
קלכתבו תוכנית ב־C שמדגימה שימוש ב־calloc() להקצאת זיכרון דינמית עם אתחול אוטומטי לאפס. על התוכנית:
- לקרוא מהמשתמש מספר שלם
sizeשמייצג את מספר המספרים השלמים שיש להקצות - להשתמש ב־
calloc()כדי להקצות באופן דינמי זיכרון למערך שלsizeמספרים שלמים - לבדוק אם הקצאת הזיכרון הצליחה — אם היא נכשלת, להדפיס
Memory allocation failed!ולסיים את התוכנית - אם ההקצאה מצליחה, להדפיס
Memory allocated and initialized to zero! - להדפיס את כל הערכים ההתחלתיים במערך כדי להדגים שהם אפס, בפורמט:
Initial values: [value1] [value2] [value3] ... - לקרוא מהמשתמש
sizeערכים של מספרים שלמים ולאחסן אותם במערך שהוקצה - להדפיס את כל הערכים המעודכנים בפורמט:
Updated values: [value1] [value2] [value3] ... - לחשב ולהדפיס את סכום כל הערכים בפורמט:
Sum: [value] - להשתמש ב־
free()כדי לשחרר את הזיכרון - להדפיס
Memory freed!כדי לאשר את הניקוי
זכרו לכלול את הכותרת <stdlib.h> כדי להשתמש ב־calloc() וב־free(). האתגר הזה מדגים את היתרון המרכזי של calloc() על פני malloc(): אתחול אוטומטי לאפס של כל הזיכרון שהוקצה.
לדוגמה, אם הקלט הוא:
3
10 20 30הפלט שלכם אמור להיות:
Memory allocated and initialized to zero!
Initial values: 0 0 0
Updated values: 10 20 30
Sum: 60
Memory freed!האתגר הזה מדגיש כיצד calloc() מספק מצב התחלתי נקי וצפוי עבור המערכים שהוקצו באופן דינמי, ומונע את ערכי הזבל הבלתי צפויים ש־malloc() עלול להשאיר.
נסו בעצמכם
#include <stdio.h>
#include <stdlib.h>
int main() {
int size;
// קראו את גודל המערך
scanf("%d", &size);
// TODO: כתבו את הקוד שלכם למטה
// השתמשו ב-calloc() כדי להקצות זיכרון למערך
// בדקו אם הקצאת הזיכרון הצליחה
// הדפיסו את הערכים ההתחלתיים (אמורים להיות אפס)
// קראו ושמרו את ערכי הקלט
// הדפיסו את הערכים המעודכנים
// חשבו והדפיסו את הסכום
// שחררו את הזיכרון שהוקצה
return 0;
}השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה לוגיקה וזרימת תוכנית
1יסודות המצביעים
מהו מצביע?הכרזה על מצביעיםאופרטור לקיחת הכתובת (&)אופרטור ביטול ההפניה (*)מצביעי NULLסיכום: יסודות המצביעים2מצביעים ומערכים
שמות מערכים כמצביעיםאיברי מערך ומצביעיםאריתמטיקה של מצביעיםהשוואת מצביעיםסיכום: מעבר על מערך באמצעות מצביעים5מצביעים ופונקציות
העברה לפי ערךהעברת מצביעים לפונקציותשינוי משתנים באמצעות מצביעיםדוגמה קלאסית: החלפההעברת מערכים לפונקציותחזרה: ארגומנטים של מצביעי פונקציה3מערכי תווים ומחרוזות
מחרוזות כמערכי charתו הסיום nullקלט מחרוזת באמצעות scanfשימוש ב־strlen()שימוש ב־strcpy()שימוש ב־strcat()שימוש ב־strcmp()סיכום: פונקציות מחרוזת בסיסיות6ניהול זיכרון
זיכרון מחסנית לעומת ערימההקצאה דינמית - malloc()שימוש ב-sizeof() להקצאהבדיקת כישלון בהקצאהשחרור זיכרון באמצעות free()הקצאה באמצעות calloc()סיכום: מערך דינמיתרגלו בעצמכם: קומפיילר C אונליין