lisz-works

技術系だけど関係ないこと多い系ブログ

構造体配列に全て1をセットしようとmemsetを使って失敗した話

【スポンサーリンク】

プログラムのソースコード

どうもlisです。

memset関数での、配列や構造体のゼロクリアはよくやりますよね。
しかしそれ以外の値でmemset関数を使用したときにどうなるのか?ということついてを備忘録を兼ねて書いていきます。

memsetで「0」以外(「1」など)の値をセットした場合

サンプルソースです。

typedef struct {
    int value1;
    int value2;
} TEST_TBL;

void test(void) {
    TEST_TBL tbl[10];
    memset(tbl, 1, sizeof(tbl));
}

この場合、tblにセットされる値はこのようになります。

tbl[N].value1 : 0x01010101
tbl[N].value2 : 0x01010101
※tbl[0]~tbl[9]まで共通

なぜこうなるのか?

memset関数は、セットする値を第1引数のアドレスからサイズ分、1Byteずつ第2引数の値をセットしていきます。

なので1つ目のサンプルの場合、int変数の4Byte分に対して、1Byteずつ1をセットします。
そのため「0x01010101」となってしまいます。

全構造体の全変数を「1」にしたい場合

仮にtbl[0]~tbl[9]までのvalue1, value2に、それぞれ「1」をセットしたい場合、ループで個別にセットする必要があります。

typedef struct {
    int value1;
    int value2;
} TEST_TBL;

void test(void) {
    TEST_TBL tbl[10];
    for (int i = 0; i < (sizeof(tbl) / sizeof(tbl[0])); i++)
    {
        tbl[i].value1 = 1;
        tbl[i].value2 = 1;
    }
}

これによって値は全て「1」となります。

あとがき

普段ゼロクリアしかしないせいで、「全部設定値でセットしてくれる関数」みたいに勘違いしてたことがありました。

そのせいで、実行したら意味わかんない値になったことがありました(笑)
なので、何かの役に立てば幸いです……