Menu
Coddy logo textTech

スタック vs ヒープメモリ

CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 12/104。

C++プログラムでは、主に2つのメモリ領域、スタックheapを使用します。オブジェクトがどこに存在するかを理解することは、効率的でバグのないコードを書くうえで非常に重要です。

stack は高速な自動メモリです。関数内で宣言された変数はここに存在し、スコープ外に出ると自動的に破棄されます。

void example() {
    int x = 10;           // スタック割り当て
    Player player;        // スタック割り当て - 自動的に破棄される
}   // x と player はここで破棄される

heap は、より大きいものの速度が遅い memory で、手動で管理します。heap 上のオブジェクトは、明示的に delete するまで存在し続けます。

void example() {
    Player* player = new Player();  // ヒープ割り当て
    // player は削除されるまで存在する
    delete player;                   // 手動クリーンアップが必要
}

主な違い:

スタックHeap
高速な割り当て低速な割り当て
サイズに制限がある大容量
自動的なクリーンアップManual cleanup が必要
固定サイズのオブジェクト動的サイズのオブジェクト

小さく、短命なオブジェクトにはスタック allocation を使用します。オブジェクトがスコープを超えて存続する必要がある場合、またはサイズが実行時に決定される場合は、heap allocation を使用します。

ヒープメモリの削除を忘れると、C++プログラムでよくあるバグの原因であるメモリリークが発生します。

challenge icon

チャレンジ

簡単

オブジェクトがどのように作成され、破棄されるかを追跡するシンプルな Counter class を構築して、stack と heap の memory の違いを探ってみましょう。

コードを整理するために、2つのファイルを作成します。

  • Counter.h: private な name 属性(string)を持つ Counter class を define します。name を受け取り、"Creating: <name>" を prints する constructor と、"Destroying: <name>" を prints する destructor を含めます。counter の name を return する getName() method を追加します。
  • main.cpp: stack と heap の両方の allocation を実演します。input から name を Read して、次の操作を行います。
    • その name を使用して、stack に allocation された Counter を Create する
    • "HeapCounter" という name で heap に allocation された Counter を Create する
    • 両方の counter の name を、"Stack: <name>" および "Heap: <name>" の format で Print する
    • memory leak を prevent するため、heap に allocation された counter を Delete する

各オブジェクトをいつ Create して Delete するかによって、constructor と destructor のメッセージが異なる順序で表示されることを確認してください。stack オブジェクトは main() が終了すると automatically destroyed されますが、heap オブジェクトは明示的に Delete する必要があります。

​​#include "Counter.h" を使用して、header file を main.cpp に include してください。

自分で試してみよう

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

using namespace std;

int main() {
    // 入力から名前を読み取る
    string inputName;
    cin >> inputName;

    // TODO: inputNameを使用してスタック割り当てされたCounterを作成する

    // TODO: 名前"HeapCounter"でヒープ割り当てされたCounterを作成する

    // TODO: Print stack counter name in format "Stack: <name>"

    // TODO: ヒープカウンターの名前を"Heap: <name>"形式で出力する

    // TODO: メモリリークを防ぐためにヒープ割り当てされたカウンターを削除する

    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: C++オンラインコンパイラ