★ポインタ(メモリ領域の確保と解放2)★


では、配列の確保をやってみましょう。

配列は変数がつながったものですから、同じようなイメージで確保できます。

プログラムを作ってみましょう。

<sample program 167-01>

#include <stdlib.h>

#define DATA 5

int main(void)
{
    int *pData;

    pData = (int*)malloc(sizeof(int) * DATA);

    if (pData == NULL) {
        return 1;
    }

    free(pData);

    pData = NULL;

    return 0;
}

配列の確保はmalloc関数の引数に必要なバイト数を指定するだけです。

ただ、何度も書きますが直接数値を指定することが出来ません。

sizeof命令を使い、

  必要な変数のサイズ × 必要な個数

で指定します。

これで確保した配列の使い方は、通常のポインタから配列を扱う方法と同じです。

サンプルプログラムを作ります。

<sample program 167-02>

#include <stdlib.h>

#define DATA 5

int main(void)
{
    int i;

    int *pData;

    pData = (int*)malloc(sizeof(int) * DATA);

    if (pData == NULL) {
        return 1;
    }

    for (i = 0; i < DATA; i++) {
        pData[i] = i + 1;
    }

    for (i = 0; i < DATA; i++) {
        printf("pData[%d] = %d\n", i, pData[i]);
    }

    free(pData);

    pData = NULL;

    return 0;
}

<実行結果>

pData[0] = 1
pData[1] = 2
pData[2] = 3
pData[3] = 4
pData[4] = 5
続行するには何かキーを押してください・・・

ここでmalloc関数とは全く関係ない事を説明します。

随分前に説明したif文の「条件の否定」についてです。

↑のプログラムには、エラーチェックのために、

if (pData == NULL) {
    return 1;
}

というコードを書いています。

NULLというのは、「無効なポインタ」ですが、実際は「0」という数値です。

ということは、

if (pData == 0) {
    return 1;
}

と同じコードになります。

これを「条件の否定」を使って書くと、

if (!pData) {
    return 1;
}

とも書けます。

pDataの中身が NULL であれば「0」ということですから、条件的には「成り立っていない」という事です。

それに「条件の否定:!」を付けることで「成り立つ」ことになります。

つまり、失敗した場合成り立つのです。

色々なサイトでは、このようなコードを書いてあることが多いのでこれからは上記のように書くことにします。


さて、本題に戻りましょう。

malloc関数で配列が使えるようになりました。

これを使うと、通常の配列では出来なかったことが出来るようになります。

上のプログラムの定数 DATA のところを変数に変えてみます。

<sample program 167-03>

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int i;

    int *pData;

    int dataCount = 5;

    pData = (int*)malloc(sizeof(int) * dataCount);

    if (pData == NULL) {
        return 1;
    }

    for (i = 0; i < dataCount; i++) {
        pData[i] = i + 1;
    }

    for (i = 0; i < dataCount; i++) {
        printf("pData[%d] = %d\n", i, pData[i]);
    }

    free(pData);

    pData = NULL;

    return 0;
}

<実行結果>

pData[0] = 1
pData[1] = 2
pData[2] = 3
pData[3] = 4
pData[4] = 5
続行するには何かキーを押してください・・・

通常の配列では、

int dataCount = 5;

int data[dataCount];

という書き方は出来ないと説明しました。

試しにプログラムを書いてみます。

<sample program 167-04>

int main(void)
{
    int dataCount = 5;

    int data[dataCount];

    return 0;
}

これはコンパイル時に↓のエラーが出ます。

  error C2131: 式は定数に評価されませんでした
  note: エラーの原因は非定数引数または非定数シンボルへの参照です
  note: 'dataCount' の使用量を参照してください

配列の宣言時に [ ] の間に書くのは「定数」でなければなりません。


「定数」ということは、↓ではどうでしょう。

<sample program 167-05>

int main(void)
{
    const int dataCount = 5;

    int data[dataCount];

    return 0;
}

const を付けて「定数」にしました。

これだとエラーは出ません。

が、変数dataCountの中身も変更出来ません。

int data[5];

と書くのと変わりがないということです。


malloc関数を使う事で、配列のサイズを毎回変更出来るようになるのです。

これは、色々なプログラムで使える考え方になります。

次回からは、これを使ったプログラムを考えていきましょう。


次へ

戻る

目次へ