スタックオーバーフローって、そもそもナニ?

はじめに
プログラミングをしていると、「スタックオーバーフロー」という言葉を耳にすることがあります。
「なんだか怖そう……」「ウイルスみたいなもの?」と思うかもしれませんが、実はこれ、プログラムの仕組みの中で起こる単純な“メモリの問題” なんです。
今回は、難しい専門用語をなるべく使わずに、「スタックオーバーフローとは何か」をわかりやすく見ていきましょう。
最初に「スタック」とは?
“スタック(stack)”とは、英語で「積み重ねる」という意味。
プログラムの世界でも「積み重ねるようにデータを管理する仕組み」のことを指します。
たとえば、
コンピュータが関数(処理のかたまり)を呼び出すたびに、「次にどこへ戻るか」や「使っている変数の情報」などを、スタックという特別な領域に順番に積み重ねていきます。
これはまるで、「お皿を上にどんどん積んでいく」ようなもの。最後に積んだお皿から順に片付けていく──これが“スタック”の基本ルールです。
(この動きを専門用語で「LIFO:Last In, First Out」と言います)
合わせて読みたい
オーバーフローとは?
“オーバーフロー(overflow)”は、「あふれる」という意味です。
つまり、「スタックオーバーフロー」は、スタックにデータを積みすぎて、入りきらなくなり、あふれ出した状態
を指します。たとえば、 お皿をどんどん積みすぎて、タワーが崩れてしまうようなものです。
プログラムにとっては非常に危険な状態で、多くの場合、実行中にエラーを出して強制終了します。
どうしてそんなことが起きるの?
一番よくある原因は、再帰の使いすぎです。
▶ 再帰とは?
関数の中で「自分自身を呼び出す」ことを言います。
少し便利なテクニックなのですが、
もし「終わりの条件」を正しく書かないと、永遠に自分を呼び続けてしまうことがあります。
def hello():
print("Hello!")
hello() # ← 終わりがない!
このプログラムを実行すると、hello() が自分を呼び出し続けて、ずーっと止まりません。
関数を呼び出すごとにスタックにデータが追加されていくため、やがてスタックがいっぱいになり、
「スタックオーバーフロー」というエラーが発生します。
実際のプログラムでは?
多くの言語では、スタックの大きさに上限があります。
「1回呼び出すごとに少しずつメモリを使う」ため、それを超えるとシステムが
「もう無理!これ以上は積めません!」と叫ぶ――
それがスタックオーバーフローです。
Pythonでは「RecursionError」というメッセージが出たり、C言語やC++では「segmentation fault(セグメンテーションフォルト)」と表示されたりします
合わせて読みたい
どうしたら防げる?
スタックオーバーフローは、ちょっとした工夫で防げます。
- 再帰を使うときは、必ず終了条件を書くこと!
- 深すぎる関数のネスト(入れ子)を避けること!
- 必要なら、ループ(forやwhile)で書き直すこと!
プログラムを整理して、
「ちゃんと終わる処理」になっていれば、オーバーフローを起こすことはありません。
まとめ
| 用語 | 意味 |
| スタック | 関数などを「積む」ための領域 |
| オーバーフロー | あふれること |
| スタックオーバーフロー | スタックにデータを積みすぎてあふれた状態 |
「スタックオーバーフロー」は難しいエラー名に見えますが、本質は「積みすぎてあふれた」というシンプルな現象です。 慣れてくると、「あ、再帰が止まってないんだな」などとすぐピンと来るようになります。
エラーに出会ったときは、慌てずに「どこで積みすぎているのか?」を確認してみましょう。
余談:名前が同じあのサイトは?
実は、有名なQ&Aサイト 「Stack Overflow」 は、まさにこのエラー名から命名されています。
「みんなの質問や知識があふれ出す場所」──という意味が込められているようです。


