動的なメモリ領域の確保(malloc, free / new, delete)

(ブログ記事の一覧は「こちら」)

ポインタを使用する有効な方法は、データ領域を確保する場合です。

C言語は、C言語の標準関数であるmalloc関数/free関数でデータ領域の確保/解放を行い、C++は、new/delete演算子でデータ領域の確保/解放を行います。

Javaの場合は、関数内でnewを使用して確保したデータ領域は、関数の処理が終わると自動で解放していました。これはJavaの言語の大きな特徴でもありました。
C言語C++の場合、関数内でmalloc関数/newを使用して確保したデータ領域は、関数の処理が終わる前にデータ領域の解放を行う必要があります。そうしないと、確保したデータ領域が使用し続けていると判断され、コンピュータのメモリ領域をどんどん使用してしまうことになり、結果的にコンピューターの速度に影響することになります。
一見、面倒な仕様に思えるかもしれませんが、プログラム内でデータ領域の解放を指定することで、結果的にプログラム全体の処理は格段に速くなります。また、組込み機器などメモリ領域が限られるデバイスに対しては、プログラム内で確保しているデータ量が把握できることも強みになります。これらのことが、今でもC言語を利用される理由の1つでもあります。

先ほどのページのサンプルとの違いとして、ポインタで使用するデータ領域を指定する場合について確認してみましょう。

malloc, free(C言語

サンプルを以下に示します。ファイル名は、sample3.c として作成してください。

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

void testPointer2() {
    int i = 0;

    int array[3];
    array[0] = 100;
    array[1] = 200;
    array[2] = 300;

    // 動的なメモリ領域の確保
    int *p = (int *)malloc(3 * sizeof(int));

    // 値を代入
    for (i = 0; i < 3; i++) {
        *(p + i) = array[i];
    }
    
    printf("Pointer: %d %d %d\n", *p, *(p + 1), *(p + 2));

    // 動的なメモリ領域の解放
    free(p);
}

int main(void)
{
    testPointer2();
    return 0;
}

C言語の標準関数であるmalloc関数を使用して、ポインタで使用するデータ領域を定義します。

 int *p = (int *)malloc(3 * sizeof(int));

使用したデータ領域は、free関数を使用して、プログラムの終了時に解放する必要があります。

 free(p);

new, delete (C++)

newを使用したデータ領域の確保は、C言語ではなくC++の文法になります。
malloc, free から new, delete に書き換えたサンプルは以下になります。 ファイル名は、sample4.cpp として作成してください。

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

void testPointer3() {
    int i = 0;

    int array[3];
    array[0] = 100;
    array[1] = 200;
    array[2] = 300;

    int *p = new int[3];

    for (i = 0; i < 3; i++) {
        *(p + i) = array[i];
    }

    printf("Pointer: %d %d %d\n", *p, *(p + 1), *(p + 2));

    delete[] p;
}

int main(void)
{
    testPointer3();
    return 0;
}