Code Fix

初級

Index was outside the bounds of the array の原因と直し方

配列やリストの範囲外アクセスで実行時に発生します。ループの境界条件の誤りが典型的な原因です。

エラーメッセージの読み方

Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
System
名前空間 — System なら標準の基本例外です
IndexOutOfRangeException
例外クラス — 何が起きたか。ここを検索するのが最短です
Index was outside the bounds of the array.
詳細メッセージ — どの値が問題だったか
at Program.Main(String[] args) in Program.cs:line 4
発生箇所 — スタックトレースの先頭行

このエラーが出る典型パターン

パターン1

 1  class Program {
 2      static void Main(string[] args) {
 3          int[] nums = { 1, 2, 3 };
 4          System.Console.WriteLine(nums[5]);
                                          ^
 5      }
 6  }
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array. at Program.Main(String[] args) in Program.cs:line 4

配列の添字は0から始まり、末尾はLength-1です。3個の配列に5番目の要素はありません。

直し方: 5 を 1 にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  class Program {
 2      static void Main(string[] args) {
 3          int[] nums = { 10, 20, 30 };
 4          for (int i = 0; i <= nums.Length; i++) {
                               ^
 5              System.Console.WriteLine(nums[i]);
 6          }
 7      }
 8  }
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array. at Program.Main(String[] args) in Program.cs:line 5

ループの継続条件が<=だと、末尾を1つ超えたインデックスまでアクセスしてしまいます。

直し方: <= を < にします。

この問題を解いてみる →

パターン3

 1  class Program {
 2      static void Main(string[] args) {
 3          int[] nums = { 1, 2, 3 };
 4          int idx = -1;
                       ^
 5          System.Console.WriteLine(nums[idx]);
 6      }
 7  }
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array. at Program.Main(String[] args) in Program.cs:line 5

C#の配列は負のインデックスを末尾からの参照として扱いません(Pythonとは違います)。

直し方: -1 を 0 にします。

この問題を解いてみる →

パターン4

 1  class Program {
 2      static void Main(string[] args) {
 3          int[] vals = { 4, 8, 15 };
 4          System.Console.WriteLine(vals[9 ]);
                                           ^
 5      }
 6  }
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array. at Program.Main(String[] args) in Program.cs:line 4

要素数3の配列に添字9はありません。範囲外アクセスはIndexOutOfRangeExceptionになります。

直し方: 9 を 0 にします。

この問題を解いてみる →

パターン5

 1  class Program {
 2      static void Main(string[] args) {
 3          int[] data = { 1, 2, 3, 4 };
 4          int idx = 4 ;
                       ^
 5          System.Console.WriteLine(data[idx]);
 6      }
 7  }
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array. at Program.Main(String[] args) in Program.cs:line 5

要素数4の配列で使える添字は0〜3までです。4は1つ超えています。

直し方: 4 を 3 にします。

この問題を解いてみる →

よくある誤解

配列の範囲外アクセスはコンパイルエラーにならず、実行時に初めて発覚します。ループの継続条件の<=は特に見落としやすい原因です。

実務での勘所

C# 8以降は、末尾からの位置を表すIndex型(^1で「末尾から1番目」)や、範囲を表すRange型(arr[1..3]のようなスライス構文)が導入されました。従来はarr[arr.Length - 1]のように自分で引き算していた「最後の要素」へのアクセスを^1のように書けるようになり、この手の境界計算そのものを手で書く場面を減らせます。境界条件の計算をコンパイラや言語機能に任せられる場面では、任せたほうが間違いが減ります。

演習をはじめる

関連するエラー

他の言語ではどうなるか

広告
広告スロット(未設定)