C言語

【C言語】第4章第8回:動的メモリ確保:mallocとfreeの使い方

動的メモリ管理は、C言語でメモリを効率的に活用するために重要なスキルです。この章では、動的メモリを確保するためのmallocと、それを解放するfreeの使い方を徹底解説します。

1. 動的メモリ確保とは?

動的メモリ確保は、プログラムの実行中に必要なメモリを確保する方法です。

静的メモリ確保:プログラムのコンパイル時に確保されるメモリ。

動的メモリ確保:実行時に必要なサイズを指定して確保されるメモリ。

動的メモリ確保の主な利点:

  • プログラムの実行中にメモリサイズを柔軟に変更できる。
  • メモリ使用量を効率的に管理できる。

2. mallocの基本

mallocは、動的メモリを確保するための関数です。以下の形式で使用します:

void *malloc(size_t size);

ここで:

  • sizeは、確保するメモリのサイズ(バイト単位)。
  • 戻り値は、確保されたメモリの先頭アドレス(ポインタ)。
  • メモリ確保が失敗すると、NULLが返されます。

例:整数1個分のメモリを確保

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

int main() {
    int *ptr = (int *)malloc(sizeof(int));

    if (ptr == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }

    *ptr = 42; // 確保したメモリに値を代入
    printf("Value: %d\n", *ptr);

    free(ptr); // メモリを解放

    return 0;
}

解説:

  • malloc(sizeof(int)): 整数1個分のメモリを確保。
  • free(ptr): 確保したメモリを解放し、メモリリークを防ぎます。

3. freeの使い方

freeは、malloccallocで確保したメモリを解放します。解放後にポインタをNULLに設定することで、安全性を向上させます。

例:freeを使用してメモリを解放

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

int main() {
    int *ptr = (int *)malloc(5 * sizeof(int));

    if (ptr == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }

    for (int i = 0; i < 5; i++) {
        ptr[i] = i + 1; // 配列の初期化
    }

    free(ptr); // メモリを解放
    ptr = NULL; // ポインタをNULLに設定

    return 0;
}

解説:

  • メモリ解放後にptr = NULL;を設定することで、ダングリングポインタを防止します。

4. mallocとfreeの応用

例:動的配列を使用したプログラム

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

int main() {
    int n;
    printf("Enter the size of the array: ");
    scanf("%d", &n);

    int *arr = (int *)malloc(n * sizeof(int));
    if (arr == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        arr[i] = i + 1;
    }

    printf("Array elements: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    free(arr);

    return 0;
}

解説:

  • mallocを使ってユーザーが指定したサイズの配列を動的に確保。
  • 配列を操作した後、必ずfreeでメモリを解放します。

5. 練習問題

以下の課題に挑戦して、mallocfreeの使い方を練習しましょう。

  1. 動的に文字列を確保し、ユーザー入力を保存して出力するプログラムを作成してください。
  2. 動的に2次元配列を割り当て、すべての要素を初期化するプログラムを作成してください。
  3. 動的に割り当てられた配列のサイズを変更し、新しい要素を追加するプログラムを作成してください。

6. 練習問題の解答と解説

問1の解答

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

int main() {
    char *str;
    int length;

    printf("Enter the length of the string: ");
    scanf("%d", &length);

    str = (char *)malloc((length + 1) * sizeof(char)); // +1は終端文字用
    if (str == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }

    printf("Enter the string: ");
    scanf(" %[^\n]", str); // 入力を保存

    printf("You entered: %s\n", str);

    free(str); // メモリを解放

    return 0;
}

7. まとめ

mallocfreeを使用することで、効率的なメモリ管理が可能になります。動的メモリ確保の基本を理解し、次のステップとしてより高度な操作に挑戦してみましょう。