工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> C言語

C言語 動的メモリ確保: malloc, calloc, realloc, free をマスターする

C言語における動的メモリ確保

このガイドでは、標準ライブラリ関数malloc()、calloc()、realloc()、free()を用いたC言語の動的メモリ確保を、明確な例とベストプラクティスとともに解説します。

なぜ動的確保を使うのか?

静的配列はコンパイル時に固定サイズで宣言されるため、実行時に無駄なスペースが生じたり、容量不足になったりします。動的確保なら、プログラム実行中に必要なメモリ量を正確に要求できます。

これら4関数はすべて<stdlib.h>ヘッダで定義され、ヒープメモリを制御された方法で管理します。


malloc() – バイトブロックを確保

mallocは「memory allocation」の略です。指定サイズ(バイト単位)の連続したメモリブロックを確保し、任意のポインタ型にキャスト可能なvoid *型ポインタを返します。

構文

ptr = malloc(size_in_bytes); // 必要なら目的の型にキャスト

例

float *ptr = malloc(100 * sizeof(float)); // 一般的なシステムで400バイト

ここでは、ptrが400バイトブロックの先頭バイトを指します。要求が失敗するとmallocはNULLを返します。C言語では不要なキャストは避けるのが推奨されます。型付きポインタに代入する際、コンパイラが型を推論できます。


calloc() – 確保とゼロ初期化

callocは「contiguous allocation」の略。mallocと異なり、確保したブロックの全ビットをゼロで初期化するため、数値型やポインタに対して安全です。

構文

ptr = calloc(num_elements, size_of_each_element);

例

float *ptr = calloc(25, sizeof(float)); // 25個のゼロ初期化されたfloat要素

確保失敗時はNULLが返されます。


free() – 確保メモリの解放

mallocやcallocで取得したメモリは、明示的に解放するまで持続します。free()はブロックを解放し、メモリをヒープに返却して再利用可能にします。

構文

free(ptr);

NULLポインタに対するfree呼び出しは安全で、何もしません。


例1: malloc()とfree()の使用

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    int n, i, *ptr, sum = 0;
    printf("要素数を入力: ");
    scanf("%d", &n);
    ptr = malloc(n * sizeof(int));
    if (!ptr) {
        fprintf(stderr, "Error: memory not allocated.\n");
        return EXIT_FAILURE;
    }
    printf("要素を入力: ");
    for (i = 0; i < n; ++i) {
        scanf("%d", ptr + i);
        sum += *(ptr + i);
    }
    printf("Sum = %d\n", sum);
    free(ptr);
    return EXIT_SUCCESS;
}

出力

要素数を入力: 3
要素を入力: 100 20 36
Sum = 156

例2: calloc()とfree()の使用

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    int n, i, *ptr, sum = 0;
    printf("要素数を入力: ");
    scanf("%d", &n);
    ptr = calloc(n, sizeof(int));
    if (!ptr) {
        fprintf(stderr, "Error: memory not allocated.\n");
        return EXIT_FAILURE;
    }
    printf("要素を入力: ");
    for (i = 0; i < n; ++i) {
        scanf("%d", ptr + i);
        sum += *(ptr + i);
    }
    printf("Sum = %d\n", sum);
    free(ptr);
    return EXIT_SUCCESS;
}

出力

要素数を入力: 3
要素を入力: 100 20 36
Sum = 156

realloc() – 既存確保のリサイズ

現在の確保が小さすぎる、または大きすぎることが判明した場合、realloc()は既存データを保持したまま(新サイズまで)サイズを調整します。

構文

ptr = realloc(ptr, new_size_in_bytes);

再確保されたブロックへのポインタ、または失敗時NULLを返します。メモリリークを防ぐため、結果を一時ポインタにまず格納してください。

例3: realloc()の使用

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    int *ptr, i, n1, n2;
    printf("初期サイズを入力: ");
    scanf("%d", &n1);
    ptr = malloc(n1 * sizeof(int));
    if (!ptr) {
        fprintf(stderr, "Allocation failed.\n");
        return EXIT_FAILURE;
    }
    printf("再確保前のアドレス:\n");
    for (i = 0; i < n1; ++i) printf("%p\n", ptr + i);
    printf("\n新サイズを入力: ");
    scanf("%d", &n2);
    int *tmp = realloc(ptr, n2 * sizeof(int));
    if (!tmp) {
        fprintf(stderr, "Reallocation failed.\n");
        free(ptr);
        return EXIT_FAILURE;
    }
    ptr = tmp;
    printf("再確保後のアドレス:\n");
    for (i = 0; i < n2; ++i) printf("%p\n", ptr + i);
    free(ptr);
    return EXIT_SUCCESS;
}

典型的な出力

初期サイズを入力: 2
再確保前のアドレス:
0x7ffc12345670
0x7ffc12345674
新サイズを入力: 4
再確保後のアドレス:
0x7ffc12345670
0x7ffc12345674
0x7ffc12345678
0x7ffc1234567c

これら4関数をマスターし、適切なエラーハンドリングを適用することで、あらゆるCアプリケーションでヒープメモリを安全かつ効率的に管理できます。

C言語

  1. ROM、PROM、EPROM、EEPROMの理解:設計、プログラミング、識別
  2. マイクロプロセッサ:ストアドプログラムコンピューティングの進化
  3. ダイナミックプライシングが伝統小売に回帰:なぜそれは不可避なのか
  4. Cervoz、産業用AIおよびIoTソリューション向け高度DDR4-2666メモリを発売
  5. C++メモリ管理の極意:newとdeleteのエキスパート活用法
  6. C++動的配列の確保をマスター:コード例付き実践ガイド
  7. C言語のcalloc():ゼロ初期化メモリ割り当てと実践例
  8. C言語のrealloc()活用ガイド:構文、ベストプラクティス、実例
  9. C言語動的メモリ管理:calloc、malloc、freeの解説
  10. C++動的メモリ管理完全解説:スタックとヒープ、new/delete
  11. Java 10でヒープをNV-DIMMに割り当て:-XX:AllocateHeapAtオプション