Menu
Coddy logo textTech

זיכרון Stack לעומת Heap

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C++ של Coddy. שיעור 12 מתוך 104.

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

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

void example() {
    int x = 10;           // הקצאה במחסנית
    Player player;        // הקצאה במחסנית - מושמד אוטומטית
}   // x ו-player מושמדים כאן

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

void example() {
    Player* player = new Player();  // הקצאה בערימה
    // player קיים עד למחיקתו
    delete player;                   // נדרש שחרור ידני של הזיכרון
}

הבדלים עיקריים:

מחסניתערימה
הקצאה מהירההקצאה איטית יותר
גודל מוגבלקיבולת גדולה
ניקוי אוטומטינדרש ניקוי ידני
אובייקטים בגודל קבועאובייקטים בגודל דינמי

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

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

challenge icon

אתגר

קל

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

תיצור שני קבצים כדי לארגן את הקוד שלך:

  • Counter.h: הגדר מחלקת Counter עם מאפיין פרטי בשם name (מחרוזת). כלול בנאי שמקבל שם ומדפיס "Creating: <name>", וכן מפרק שמדפיס "Destroying: <name>". הוסף מתודה בשם getName() שמחזירה את שם המונה.
  • main.cpp: הדגם הקצאה הן במחסנית והן בערימה. קרא שם מהקלט, ואז:
    • צור Counter שיוקצה במחסנית, באמצעות השם הזה
    • צור Counter שיוקצה בערימה, עם השם "HeapCounter"
    • הדפס את שמות שני המונים בפורמט "Stack: <name>" ו-"Heap: <name>"
    • מחק את המונה שהוקצה בערימה כדי למנוע דליפת זיכרון

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

כלול את קובץ הכותרת שלך ב-main.cpp באמצעות #include "Counter.h".

נסו בעצמכם

#include <iostream>
#include <string>
#include "Counter.h"

using namespace std;

int main() {
    // קרא את השם מהקלט
    string inputName;
    cin >> inputName;

    // TODO: צור Counter שמוקצה במחסנית באמצעות inputName

    // TODO: צור Counter שמוקצה בערימה בשם "HeapCounter"

    // TODO: הדפס את שם המונה שבמחסנית בפורמט "Stack: <name>"

    // TODO: הדפס את שם המונה שבערימה בפורמט "Heap: <name>"

    // TODO: מחק את המונה שמוקצה בערימה כדי למנוע דליפת זיכרון

    return 0;
}
quiz iconבחנו את עצמכם

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

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר C++ אונליין