【C言語 】
sizeof(配列)/sizeof(配列[0])
配列の要素数を求める技は
ポインタには使えない


warning: division ‘sizeof (int *) / sizeof (int)’ does not compute the number of array elements

警告:’sizeof (int *) / sizeof (int)’ は、配列の要素数を計算しません。
[-Wsizeof-pointer-div]

■この記事の概要

この記事では、C言語でsizeofを使った配列の要素数取得方法の誤解を解説しています。関数に渡された配列はポインタとして扱われるため、sizeofを用いると配列のサイズではなくポインタのサイズが得られます。正確な要素数を取得するには別途引数でサイズを渡す必要があることを説明しています。


■sizeof(配列を指すポインタ)の間違い

#include <stdio.h>
void    func(int *ary) 
{    
    //期待する配列の要素数にならない   
    size_t num = sizeof(ary)/sizeof(ary[0]);
    printf("%zu\n",num); 
}
int main(void) {
    int ary[128];
    func(ary);
}

sizeof(配列)/sizeof(配列[0])で要素数を求める技は
ポインタには使えません 。
配列に対して使ってください。

※呼び元のmain( )では ary は配列でしたが
 呼び先のfunc( )では aryはポインタです。


■sizeof(配列形式の引数)の間違い

warning: ‘sizeof’ on array function parameter ‘buf’ will return size of ‘char *’

警告:sizeof(配列形式の関数引数)では配列サイズは得られない

[-Wsizeof-array-argument]

#include    <stdio.h>
void    func(int ary[128]) 
{
    //NG:期待する配列のサイズにならない
    printf("%zu\n",sizeof(ary));
}
int main(void) {
    int ary[128];
    func(ary);
}

void func(int ary[128])

128という数字をコンパイラは無視

void func(int ary[])と同じ

関数仮引数は配列形式もポインタ形式も同じ

void func(int *buf)と同じ

このため
sizeof(ary)は
配列のサイズではなくて
ポインタのサイズが求まります。

※プログラマが期待しているのは恐らく
配列のサイズでしょう。

配列のサイズが欲しい場合は別途引数を用意して親関数からサイズを教えてもらう必要があります。

参考:

ARR01-C. 配列のサイズを求めるときに sizeof 演算子をポインタに適用しない

https://www.jpcert.or.jp/sc-rules/c-arr01-c.html