404 Not Found

404 Not Found


nginx

動的メモリ管理

[前の講義で]、変数[と]配列[はどちらも]スタック(Stack)[上に割り当てられる]――[サイズは固定]で、関数が[終了すると解放される]。

[しかし、もし][不確定な数の][データ]を保存する必要がある場合([例えば、ユーザーが]1000 [個の整数]を入力する[が、]コンパイル時には[その数が]わからない場合など)、[その際には]動的メモリ[割り当て]——ヒープ(Heap)[上に]メモリを割り当てる必要があります。


1. スタックとヒープ

(1) 1.1 [2種類の]メモリ[領域]

[比較] スタック(Stack) ヒープ(Heap)
[割り当てのタイミング] コンパイル時[確定] 実行時[確定]
[大小] [固定](コンパイル時[確定]) [可変](実行時[割り当て])
[解放のタイミング] [自動解放](function[終了]) [手動解放]([使用] delete
[効率] [高] [低]
[適用シーン] ローカル変数、配列 [動的なサイズのデータ]

(2) 1.2 [生活における]クラス[比]

[生活シーン] 番組[での対応]
[ファストフード店]([固定メニュー]、[注文したらすぐに持ち帰り]) stack
[ビュッフェ]([好きなだけ取って食べていい]) heap


2. 新規 [和] 削除

(1) 2.1 [使用] 新規 [割り当て] メモリ

[文法]:

▶ サンプル 2: 動的メモリ[管理] (難易度 ⭐)

CPP
* = new ;
▶ 試してみよう

例:

CPP
#include iostream

int main() {
 // points int
 int* p = new int; // p heap's int
 
 *p = 5; // int
 std::cout << "*p = " << *p << std::endl; // 5
 
 return 0;
}

💡 [要点]: new [返されるのは]ポインタ——[ヒープ上に割り当てられた]メモリを[指す]もの。


(2) 2.2 [使用] メモリの削除 [解放]

[文法]:

TEXT
delete ;

例:

CPP
#include iostream

int main() {
 int* p = new int;
 *p = 5;
 
 std::cout << "*p = " << *p << std::endl;
 
 delete p; // ✅ heap's
 p = nullptr; // ✅:pointer
 
 return 0;
}

💡 [黄金律]: new [と] delete [必ずペアで現れる]――new [があれば] delete [もある]。


(3) 2.3 [削除] すると [メモリリーク] が発生する

エラー例:

CPP
#include iostream

void foo() {
 int* p = new int;
 *p = 5;
 // ❌ write delete p;
} //,p, int ()

int main() {
 for (int i = 0; i < 1000000; i++) {
 foo(); // 4
 }
 //,
 return 0;
}

💡 メモリリーク: ヒープ[に割り当てられた]メモリ[が解放されず]、[アクセスすることもできない]([それを指していた]ポインタ[が破棄されてしまった]ため)。



3. [動的]配列

(1) 3.1 [使用] new [割り当て]array

[文法]:

TEXT
* = new ;

例:

CPP
#include iostream

int main() {
 int n;
 std::cout << ":";
 std::cin >> n;
 
 // points n int
 int* arr = new int[n];
 
 // ...
 for (int i = 0; i < n; i++) {
 arr[i] = i + 1;
 }
 
 // output
 for (int i = 0; i < n; i++) {
 std::cout << arr[i] << " ";
 }
 std::cout << std::endl;
 
 // (: delete, delete)
 delete arr;
 
 return 0;
}

💡 [重要]: [配列]を[解放]するには、delete([角括弧付き])を使用し、deleteは[使用しない]!


(2) 3.2 new [和] delete [ペアでなければならない]

[割り当て] [解放]
new int delete p;
new int[10] delete p;

エラー例:

CPP
int* p = new int[10];
delete p; // ❌:Using delete p;


4. [懸]ヌルポインタ(ダングリングポインタ)

(1) 4.1 [悬]nullポインタとは何か?

[懸]nullポインタとは、[解放済みの]メモリ[を指す]ポインタのことです。

CPP
#include iostream

int main() {
 int* p = new int(5);
 delete p; // ...
 
 // ❌:p Nowpointer
 std::cout << *p << std::endl; //!output,
 
 return 0;
}

💡 [解決方法]: [解放後、直ちに] nullptr に設定する:

CPP
delete p;
p = nullptr; // ✅


5. 演習:[動的]配列[ソート]

▶ サンプル 1: [配列]を使って[選択ソートを実装する] (難易度 ⭐⭐)

CPP
#include iostream

// ...
void selectionSort(int* arr, int n) {
 for (int i = 0; i < n - 1; i++) {
 int minIdx = i;
 for (int j = i + 1; j < n; j++) {
 if (arr[j] < arr[minIdx]) {
 minIdx = j;
 }
 }
 // ...
 int temp = arr[i];
 arr[i] = arr[minIdx];
 arr[minIdx] = temp;
 }
}

int main() {
 int n;
 std::cout << ":";
 std::cin >> n;
 
 int* arr = new int[n]; // points
 
 std::cout << "..." << n << ":" << std::endl;
 for (int i = 0; i < n; i++) {
 std::cin >> arr[i];
 }
 
 selectionSort(arr, n); // ...
 
 std::cout << ":" << std::endl;
 for (int i = 0; i < n; i++) {
 std::cout << arr[i] << " ";
 }
 std::cout << std::endl;
 
 delete arr; // ...
 arr = nullptr;
 
 return 0;
}
▶ 試してみよう

[動作結果]:

 5:
5 3 1 4 2:
1 2 3 4 5


6. [よくある]エラー

(1) 6.1 [重複] 削除

エラー例:

CPP
int* p = new int(5);
delete p;
delete p; // ❌:(Definebehavior)

[修正]: [解放後、直ちに] nullptr に設定(delete nullptr [は安全です])。

TEXT
delete p;
p = nullptr;

(2) 6.2 [削除] delete

エラー例:

CPP
int* arr = new int[10];
// ❌ write delete arr;

[結果]: メモリリーク。


❓ よくある質問

Q [なぜ]動的メモリ[を使う必要があるのですか]?[直接]配列[を使えば][ダメなのでしょうか]?
A [もし]コンパイル時に[サイズが]分かっているなら、[配列][を使えば][十分です]。[しかし、もし]: > - [サイズがユーザーの]入力[によって決まる] > - [サイズが非常に大きくなる可能性がある]([スタックの]容量を[超える]) > - [関数の]終了後もデータが残っている必要がある

📖 まとめ


📝 練習問題

  1. 初心者(難易度 ⭐): [使用] new [1つを割り当てる] double,[値]value 3.14を割り当て,出力[後に解放]。

  2. 中級(難易度 ⭐⭐): [ユーザーに] n を入力させ、new を使用して n のサイズを持つ int 配列を動的に割り当て、n 個の整数を入力させ、[最大値] を求めた後、[配列を解放]する。

  3. 上級(難易度 ⭐⭐⭐): [動的メモリ]を用いて、[「動的」]配列クラスを[実装する]([後で学ぶ]クラスについて、[ここではとりあえず]structを使用する):


7. 🚀 次は

[動的メモリ[割り当て]を学びました]。[次は] ポインタ[と]参照[の]実践[総合演習]([第]27[課])—— [総合的な]演習を通じて、[これまでに学んだすべての知識を]定着させましょう!

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%