配列の領域外のアクセス時のエラー(Go言語)
普段はGo言語を使っているのですが、以下のようなコードを書いて、0〜9以外の値を入力するとアクセスエラーが発生します。
例えば、以下のようなプログラムを書いて実行してみます。
package main
import "fmt"
func main() {
a := make([]int, 10)
var x int
fmt.Print("x = ")
fmt.Scan(&x)
a[x] = 1
}
ここで、10
を入力すると配列外参照になるので、当然エラーが発生してくれます。
x = 10
panic: runtime error: index out of range [10] with length 10
C++の場合
配列の場合
配列の場合は、エラーが発生しないのはC言語と同じなので知っていました。
例えば、以下のようなプログラムを書いた場合、10
を入力してもエラーが発生しません。この場合、領域外が書き換えられてしまします。
#include <iostream>
int main()
{
int a[10];
int x;
std::cout << "x = ";
std::cin >> x;
a[x] = 1;
return 0;
}
std::array, std::vectorの場合
ここを勘違いしていました。vectorなどを使った場合は領域外参照でエラーが発生してくれるものと考えいました。
例えば、以下のようなプログラムを書いて10
を入力するとGoと同じようにindexエラーが発生すると考えいましたが、実際に書いて動かしてみるとエラーは発生しません。
#include <iostream>
#include <vector>
int main()
{
std::vector<int> a(10);
int x;
std::cout << "x = ";
std::cin >> x;
a[x] = 1;
return 0;
}
リファレンスを見ると、以下のようat
をつかって書けばに書けば領域外参照のエラーが発生するようです。
#include <iostream>
#include <vector>
int main()
{
std::vector<int> a(10);
int x;
std::cout << "x = ";
std::cin >> x;
a.at(x) = 1;
return 0;
}
x = 10
libc++abi: terminating due to uncaught exception of type std::out_of_range: vector
ググってみると、以下のような記事がありました。
コピペすると(たぶん)どこでvectorを範囲外参照しているかがわかるソースコード(を作りたい)
C++20以降であればこの記事のコードを貼り付けると一応チェックできるようです(自分の環境ではno type named 'source_location' in namespace 'std'
となり、チェックできず)。
最近モダン言語に慣れてしまったせいで、領域外参照は当然のようにチェックしてくれると思っていました。久しぶりにC++を使って気をつけなきゃいけないと思い記事にしました。
まぁ、チェックしていたら速度面で不利になるので当然といえば当然の実装なんですけど・・・
(追記)
思ったより、色々コメントをいただいています。私もC言語、C++言語をメインでずっと使ってきていたので、C/C++の言語のポリシーはある程度理解しているつもりです。ただ、久しぶりにC++を使うと、プログラマ側の負担が大きな言語だと感じました(スキルが必要と言い換えることも可能かも)。
良くも悪くも、そこがC言語なのですが。