index out of bounds パニックの原因と直し方
存在しない添字でVecや配列にアクセスすると、コンパイルは通りますが実行時にパニックしてプログラムが異常終了します。
エラーメッセージの読み方
thread 'main' panicked at main.rs:3:26:
main.rs- ファイル名
3- 行番号 — 実際にクラッシュした行
26- 列番号
panicked- パニック — 実行時に回復不能な状態になったことを示します。tryやResultで捕まえない限り、そのままプロセスが終了します
index out of bounds: the len is 3 but the index is 5- 詳細メッセージ — どの値が問題だったか
このエラーが出る典型パターン
パターン1
1 fn main() { 2 let scores = vec![85, 90, 78]; 3 println!("{}", scores[5]); ^ 4 }
thread 'main' panicked at main.rs:3:26:
index out of bounds: the len is 3 but the index is 5
scoresの要素数は3なので、有効な添字は0から2までです。5は範囲外なのでパニックします。
直し方: 5 を 1 にします。
広告
広告スロット(未設定)
パターン2
1 fn main() { 2 let prices = vec![100, 250, 300]; 3 println!("{}", prices[10]); ^ 4 }
thread 'main' panicked at main.rs:3:26:
index out of bounds: the len is 3 but the index is 10
添字が変数や計算結果の場合、コンパイラは範囲を事前にチェックできません。範囲外アクセスは実行時にしか分かりません。
直し方: 10 を 0 にします。
パターン3
1 fn main() { 2 let temps = vec![36, 37, 38, 39]; 3 println!("{}", temps[8]); ^ 4 }
thread 'main' panicked at main.rs:3:25:
index out of bounds: the len is 4 but the index is 8
要素数ちょうどの添字(この場合4)も範囲外です。最後の要素の添字は要素数より1小さい値になります。
直し方: 8 を 3 にします。
パターン4
1 fn main() { 2 let ages = vec![20, 25, 30]; 3 println!("{}", ages[6]); ^ 4 }
thread 'main' panicked at main.rs:3:24:
index out of bounds: the len is 3 but the index is 6
Vecの範囲外アクセスは、C言語のように未定義動作にはならずパニックとして安全に検出されます。
直し方: 6 を 2 にします。
パターン5
1 fn main() { 2 let counts = vec![5, 10, 15, 20, 25]; 3 println!("{}", counts[9 ]); ^ 4 }
thread 'main' panicked at main.rs:3:26:
index out of bounds: the len is 5 but the index is 9
要素数を勘違いしていると、範囲外の添字を指定してしまいパニックの原因になります。
直し方: 9 を 4 にします。
よくある誤解
「範囲外にアクセスしてもコンパイラが事前に止めてくれるはず」という思い込みは誤りです。添字が変数の場合、境界チェックは実行時にしか行えないため、コンパイルは通ってしまいます。
まとめ
index out of bounds パニックの原因と直し方は初級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。