スタック 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++プログラムでよくあるバグの原因であるメモリリークが発生します。
チャレンジ
簡単オブジェクトがどのように作成され、破棄されるかを追跡するシンプルな Counter class を構築して、stack と heap の memory の違いを探ってみましょう。
コードを整理するために、2つのファイルを作成します。
Counter.h: private なname属性(string)を持つCounterclass を 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 する
- その name を使用して、stack に allocation された
各オブジェクトをいつ 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;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタ引数付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ詳解Rule of Three / Five / Zeroまとめ - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () 演算子のオーバーロード型変換演算子まとめ:Matrix クラス自分で練習してみよう: C++オンラインコンパイラ