sizeofが配列の要素数ではなくポインタのサイズを返す
配列に対するsizeofは配列全体のバイト数を返しますが、関数の引数として渡された配列はポインタに変わっているため、同じsizeofが8(ポインタのサイズ)を返してしまいます。
なぜエラーが出ないのか
出力: 2
(エラーなし)- Cは何も報告しません。コンパイルも実行も正常に完了するためです
出力: 2- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 #include <stdio.h> 2 3 int main(void) { 4 int nums[5] = {1, 2, 3, 4, 5}; 5 int *p = nums; 6 int count = sizeof(p ) / sizeof(int); ^ 7 printf("%d\n", count); 8 return 0; 9 }
pはnumsの先頭要素を指すポインタで、sizeof(p)はポインタ自体のサイズ(8バイト)を返します。配列全体のバイト数が欲しいときは、配列そのものにsizeofを使う必要があります。
直し方: p を nums にします。
パターン2
1 #include <stdio.h> 2 3 int main(void) { 4 double prices[4] = {9.5, 3.2, 7.1, 4.4}; 5 double *p = prices; 6 int count = sizeof(p ) / sizeof(double); ^ 7 printf("%d\n", count); 8 return 0; 9 }
ポインタ変数のsizeofは指している型によらず常にポインタ自身のサイズです。要素数を得るには配列の変数名に直接sizeofを使います。
直し方: p を prices にします。
パターン3
1 #include <stdio.h> 2 3 int main(void) { 4 char letters[6] = {'a', 'b', 'c', 'd', 'e', 'f'}; 5 char *p = letters; 6 int count = sizeof(p ) / sizeof(char); ^ 7 printf("%d\n", count); 8 return 0; 9 }
char型の配列でも同じ罠があります。ポインタpのsizeofは要素の型と無関係に8(ポインタのサイズ)を返すため、要素数の計算には使えません。
直し方: p を letters にします。
パターン4
1 #include <stdio.h> 2 3 int main(void) { 4 long ids[3] = {100, 200, 300}; 5 long *p = ids; 6 int count = sizeof(p ) / sizeof(long); ^ 7 printf("%d\n", count); 8 return 0; 9 }
long型の配列でも同じです。ポインタのsizeofは要素の型に関係なく常にポインタ自身のサイズになります。
直し方: p を ids にします。
パターン5
1 #include <stdio.h> 2 3 int main(void) { 4 float weights[7] = {1, 2, 3, 4, 5, 6, 7}; 5 float *p = weights; 6 int count = sizeof(p ) / sizeof(float); ^ 7 printf("%d\n", count); 8 return 0; 9 }
要素数が増えても規則は同じです。要素数を得るには配列の変数名に直接sizeofを使う必要があります。
直し方: p を weights にします。
よくある誤解
配列を関数に渡しても「配列そのもの」が渡されると思いがちですが、Cでは配列は関数の引数になった瞬間に先頭要素へのポインタに変換されます(配列のdecay)。要素数の情報は失われるため、関数内でsizeofから要素数を復元することはできません。
実務での勘所
配列の要素数を求める定石はsizeof(arr) / sizeof(arr[0])ですが、これが正しく働くのは配列がまだポインタに変換されていない、宣言されたスコープの中だけです。関数に渡した後の引数としてのarrに対して同じ式を書くと、ポインタのサイズを要素のサイズで割った無意味な値になります。この制約のため、Cでは配列を関数に渡すときは、要素数を表す引数を別途一緒に渡すのが標準的な作法です(void f(int *arr, size_t n)のように)。