読者です 読者をやめる 読者になる 読者になる

Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

C/C++で配列の長さの求め方

スポンサードリンク

f:id:fa11enprince:20150730082309j:plain
C/C++で配列の長さの求め方です。
超基本中の基本なのですが、しばらくC/C++の配列を使っていないと
アレレってことになってしまいます。
今日はそれでハマりました。
sizeofを使って配列の長さ(要素数)を求めたはずが、
なんでか落ちる…バッファオーバーランっぽい。
こんなコードです。

int hoge[20];
for (int i = 0; i < sizeof(hoge); i++)
{
    hoge[i] = 0;   // バッファオーバーランしちゃうよーぎえー(´・ω・`)
}

memset()使えよとかそういう問題ではありません。
ちなみに、次のパターンなら通常の環境の場合バッファオーバーランにはなりません
バッファオーバーランする環境があるのか謎ですが……

char hoge[20];
for (int i = 0; i < sizeof(hoge); i++)
{
    hoge[i] = 0;   // おっけー!一応ね…
}

そうです。char型の場合だと1バイトなので割る必要はないですが、
int型だと1つあたり4byteなので(環境依存ですが……)一つあたりの型のの長さの分、
割ってやらなければいけません。
結論。配列の長さを求めるには
sizeof(array) / sizeof(array[0])としてやる。

検証用のコード(C99)


※C99以前ではconst定数を配列のサイズに指定することができないので、
その場合は#defineするしかありません。

実行結果

sizeof(int) : 4
sizeof(arr[0]) : 4
sizeof(arr) : 200
sizeof(arr) / sizeof(int) : 50
sizeof(arr) / sizeof(arr[0]) : 50

検証用のコード(C++)

実行結果

sizeof(int) : 4
sizeof(arr[0]) : 4
sizeof(arr) : 200
sizeof(arr) / sizeof(int) : 50
sizeof(arr) / sizeof(arr[0]) : 50

マクロを使ったおまけ(C++)

※上記のマクロは多少落とし穴がありますが、
そこはそんなあほなことするなよでよろしくお願いします。
頑張っているところがありました。

※なお、たまに見かける、やっちまったなーなコードは関数で配列をポインタとして
受け取ったもの*1
sizeofして配列の長さを出すつもりが、
実際にはポインタのサイズ(長さ)しか出していないというものです。
そういう場合は長さを渡すか、その配列の長さ用に定義した定数を使うしかないです。

配列のサイズを求める関数とかって標準であるのかなぁ……

*1:この場合 int *arr と受取ろうが、 int arr[] と受取ろうが関数の引数の場合、どっちも単なるポインタとなってしまう