【C言語】
配列の要素数とサイズは違う
sizeの変数名は誤読しやすい

配列の要素数  !=  配列のサイズ

warning: ‘memset’ used with length equal to number of elements without multiplication by element size

警告:memset()の第3引数には配列の要素数ではなくサイズを指定して下さい
[-Wmemset-elt-size]

■配列の要素数とサイズを間違った例

#include    <string.h>
int main(void)
{
    //NG:要素数とサイズは違う
    int ary[1024];
    memset(ary,0,1024);

    //NG:sizeという変数名が誤解を与える
    size_t  size = sizeof(ary) / sizeof(ary[0]) ;
    memset(ary,0,size);             
}

memset()の第三引数に記述するのは要素数ではなくてサイズです。
配列の型がchar 型の時は要素数とサイズは同じで混同しがちですが
char 以外の時は配列要素数と配列サイズは別ものです。

又、9行目のように配列の要素数を求めた結果を
size という名前の変数名に代入すると
要素数なのかサイズなのかで混乱します。


■修正例1(推奨しないsizeof(型)*要素数)

//ダメな修正:型や要素数を間違う可能性がある
#include <string.h>
int main(void)
{
    int ary[1024];
    memset(ary,0,sizeof(int)*1024);

    size_t  size = sizeof(ary) / sizeof(ary[0]) ;
    memset(ary,0,sizeof(int)*size);
}

sizeof(型)*要素数 
型や要素数を間違える可能性が高いのでこの修正は避けましょう。


■修正例2(推奨するsizeof(変数名))

//正しい修正:変数に対してsizeof()を使用する
#include <string.h>
int main(void)
{  
    int ary[1024];
    memset(ary,0,sizeof(ary));       
}

sizeof(変数名)
こちらを推奨します。


■修正例3(強く推奨する)

//最も良い修正:記述量が少なく、効率も良い
int main(void)
{
    int ary[1024] ={0};            
}

宣言時に0で初期化すると全要素0で初期化されます。記述量が少ないので間違える事もなく、かつ実行速度が高速です。


■gccで警告が出ない例

//  gcc11で検出できなかった
void fz(int   some_count)
{
    int ary[some_count];
    memset(ary,0,some_count);//(1) 可変長配列
    
    int buf[1024];
    memset(buf,0,sizeof(1024));//(2) sizeof(定数)
}

(1) some_count は要素数でサイズではありません。
(2) sizeof(1024)はsizeof(int)と同じで結果は4固定です。
上記はgcc11で検出できませんでした。


参考:

sizeof()よりもsizeof(変数名)を使いましょう。

https://ttsuki.github.io/styleguide/cppguide.ja.html#sizeof

■アンケート

6
配列 int ary[1024]の全要素0クリアする最善の方法はどれですか?