auの日記

プログラミング初心者の日記。(auはハンドルネームです)

可変長のint型のリストの初期化方法

auです。

以前、C言語のint型の配列の初期化方法を書きました。

しかしあれは、固定長のリストでした。可変長になった場合、あの初期化方法が通用しなかったのでやり方を書いておこうと思います。

可変長の宣言

そもそも可変長のリストは以下のように宣言します。

int hoge[5+n];

こうすると、nの値によって配列の長さが変わる、可変長のリストを宣言することになります。

初期化なしで出力してみる

#include <stdio.h>

int main(int argc, char* argv[]) {
    int n = atoi(argv[1]);

    int hoge[5+n];

    int hoge_len = sizeof(hoge) / sizeof(hoge[0]);

    for (int j = 0; j < hoge_len; j++) {
        printf("hoge[%d]: %d\n", j, hoge[j]);
    }

    return 0;
}

// 実行結果
./a.out 20
hoge[0]: 0
hoge[1]: 0
hoge[2]: 0
hoge[3]: 0
hoge[4]: 0
hoge[5]: 0
hoge[6]: 0
hoge[7]: 0
hoge[8]: -361569280
hoge[9]: 32766
hoge[10]: 0
hoge[11]: 0
hoge[12]: 0
hoge[13]: 0
hoge[14]: 0
hoge[15]: 0
hoge[16]: 0
hoge[17]: 0
hoge[18]: 0
hoge[19]: 0
hoge[20]: 0
hoge[21]: 0
hoge[22]: 0
hoge[23]: 0
hoge[24]: -361569296

一部は0で初期化されていますが、所々意味不明な値が入ってますね。ちなみにこの意味不明な値はゴミっていうらしいです。

配列の長さを変えると、ゴミのでる箇所が変わるので本当に予測できないですね。

0で初期化する

早速0で初期化してみます。

固定長の初期化と同じ方法でやってみると...

test.c:6:14: error: variable-sized object may not be initialized
    int hoge[5+n] = {0};
             ^~~
1 warning and 1 error generated.

コンパイルの段階でエラーが起きました。可変長の変数は初期化できないみたいですね。

どうやらfor文で配列を一つずつ初期化するしかないようですね。

#include <stdio.h>

int main(int argc, char* argv[]) {
    int n = atoi(argv[1]);

    int hoge[5+n];

    int hoge_len = sizeof(hoge) / sizeof(hoge[0]);
    for (int i = 0; i < hoge_len; i++) {
        hoge[i] = 0;
    }


    for (int j = 0; j < hoge_len; j++) {
        printf("hoge[%d]: %d\n", j, hoge[j]);
    }

    return 0;
}

// 実行結果
./a.out 20
hoge[0]: 0
hoge[1]: 0
hoge[2]: 0
hoge[3]: 0
hoge[4]: 0
hoge[5]: 0
hoge[6]: 0
hoge[7]: 0
hoge[8]: 0
hoge[9]: 0
hoge[10]: 0
hoge[11]: 0
hoge[12]: 0
hoge[13]: 0
hoge[14]: 0
hoge[15]: 0
hoge[16]: 0
hoge[17]: 0
hoge[18]: 0
hoge[19]: 0
hoge[20]: 0
hoge[21]: 0
hoge[22]: 0
hoge[23]: 0
hoge[24]: 0


stringライブラリのmemsetもできるんじゃね?と思ったのですが、マシンによってはうまく初期化されないみたいです。

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {
    int n = atoi(argv[1]);

    int hoge[5+n];

    int hoge_len = sizeof(hoge) / sizeof(hoge[0]);
    
    memset(&hoge[0], 0, hoge_len);


    for (int j = 0; j < hoge_len; j++) {
        printf("hoge[%d]: %d\n", j, hoge[j]);
    }

    return 0;
}

// 実行結果
./a.out 20
hoge[0]: 0
hoge[1]: 0
hoge[2]: 0
hoge[3]: 0
hoge[4]: 0
hoge[5]: 0
hoge[6]: 0
hoge[7]: 0
hoge[8]: 0
hoge[9]: 0
hoge[10]: 0
hoge[11]: 0
hoge[12]: 0
hoge[13]: 0
hoge[14]: 0
hoge[15]: 0
hoge[16]: 0
hoge[17]: 0
hoge[18]: 0
hoge[19]: 0
hoge[20]: 0
hoge[21]: 0
hoge[22]: 0
hoge[23]: 0
hoge[24]: -499706896

見事に最後の値がゴミになりました。

for文で初期化する方がいいかもしれないですね〜