とある組み込み屋のブログ

駆け出しの組み込みソフトウェア屋が技術的なことから日常的なことまで、色々書きます。

ぽかみす

sizeof

C言語

 sizeof(型、変数、etc...);

という演算子がありますね
この演算子について恥ずかしながら色々勘違いしていました...
勉強しなおさないとですね。
少し極端な例ですが、例えばこんなプログラムがあったとして、

#include <stdio.h>

int example(int *p);
int main(){
    int array[3] = {1, 2, 3};
    int result;
    
    /* 直接sizeofで配列の要素数を求める */
    result = sizeof(array) / sizeof(int);
    printf("%d\n", result); // => 3

    /* 配列をポインタで渡して関数で大きさを求めたい */
    result = example(array);
    printf("%d\n", result); // => 3?

    return 0;
}

int example(int *p){
    return sizeof(p) / sizeof(int);
}

さて、コード上にも書いていますが、
関数にて求めた2個目のresultはどんな値を取ると思いますか?
結果から言うとこうなります。

3
1

なぜこうなるのでしょうか?
実は関数の

int example(int *p){
    return sizeof(p) / sizeof(int);
}

の部分、
sizeof()の引数にint*(intポインタ)を渡しています。
つまりこれはポインタのサイズを取得しているのです。
ポインタが確保しているメモリサイズを返しているんですね。
私のPCだと4バイト確保しているようで、これを実行すると4が出力されます。
sizeof(int)はintのバイトサイズなのでintは32ビットのため、4となります。
つまり4 / 4 = 1となり、出力のresultは1となっています。
memcpyを使う機会がありまして、その第3引数にsizeofを用いたのですが
そこにポインタを入れてしまい、いつまでも4つ分の配列の要素しかコピーできないという沼に陥っていました。。。
こういう演算子を使う時は定義を明確にして使用して濫用しないようにしたいですね。

余談

あと、マークダウン記法でソース書くときのシンタックスハイライトの言語指定ですが、
C言語ソースは小文字のcじゃないとダメなんですね。。大文字はダメらしい。。