スタックオーバーフローとは
スタックオーバーフローは、プログラムの実行スタックにあるメモリが限界を超えてしまうエラーです。通常、再帰関数の無限呼び出しにより発生します。関数が自分自身を呼び出すと、その実行情報がスタックに追加され、このプロセスが無限に続くとスタックの容量が足りなくなり、アプリケーションがクラッシュします。
スタックオーバーフローが発生する例
下記コードはスタックオーバーフローを意図的に発生させる例です。再帰関数には終了条件が設定されておらず、無限に自分自身を呼び出し続けることで、スタックの容量が足りなくなり、スタックオーバーフロー例外が発生します。
using System;
class Program
{
static void Main()
{
// 再帰処理を行う関数を呼び出す
RecursiveFunction(1);
}
// 再帰関数
static void RecursiveFunction(int counter)
{
// 再帰呼び出し回数を表示
Console.WriteLine(counter.ToString());
// 再帰的に自分自身を呼び出す
RecursiveFunction(counter + 1);
}
}
実行結果
64422
64423
64424
64425
64426
64427
Process is terminated due to StackOverflowException.
続行するには何かキーを押してください . . .
呼び出し履歴を確認すると、確かに関数 RecursiveFunction() が、自分自身を呼び出し続けています。
スタックオーバーフローの対処方法
再帰関数を使用する際は、適切な終了条件を設定することが重要です。無限に自分自身を呼び出す関数は、プログラムをクラッシュさせる原因となります。このサンプルでは、引数の値をチェックすることで再帰呼び出しを制御し、スタックオーバーフローを防ぐ方法を示しています。
using System;
class Program
{
static void Main()
{
// 再帰処理を行う関数を呼び出す
RecursiveFunction(1);
}
// 再帰関数
static void RecursiveFunction(int counter)
{
// 再帰呼び出し回数を表示
Console.WriteLine(counter.ToString());
// ★終了条件
if (counter >= 10)
{
Console.WriteLine("再帰処理の上限に達しました");
}
// 再帰的に自分自身を呼び出す
RecursiveFunction(counter + 1);
}
}
実行結果
1
2
3
4
5
6
7
8
9
10
再帰処理の上限に達しました
続行するには何かキーを押してください . . .
まとめ
本記事では、スタックオーバーフローが発生する例と対処方法について紹介しました。