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

malloc()、calloc() 関数を使用した C での動的メモリ割り当て

C 動的メモリ割り当てを学ぶ前に、次のことを理解しましょう:

C のメモリ管理はどのように機能しますか?

基本データ型を使用して変数を宣言すると、C コンパイラは スタック と呼ばれるメモリ プール内の変数にメモリ空間を自動的に割り当てます。 .

たとえば、float 変数は、宣言時に (プラットフォームに応じて) 通常 4 バイトかかります。 sizeof を使用して、この情報を確認できます。 以下の例に示すような演算子

#include <stdio.h>
int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}

出力は次のようになります:

 The size of float is 4 bytes

また、指定されたサイズの配列がメモリの連続したブロックに割り当てられ、各ブロックは 1 つの要素のサイズを持ちます:

#include <stdio.h>
int main() { float arr[10];
printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}


結果:

 The size of the float array with 10 element is 40

これまで学んだように、基本的なデータ型や配列を宣言すると、メモリは自動的に管理されます。ただし、C にはメモリを割り当てるためのプロセスがあり、プログラムを実行する (実行時) まで配列サイズが決定されないプログラムを実装できます。このプロセスは「動的メモリ割り当て」と呼ばれます .」

このチュートリアルでは、次のことを学びます-

C での動的メモリ割り当て

動的メモリ割り当て プログラミングのニーズに応じてメモリを手動で割り当ておよび解放することです。動的メモリは、ヒープと呼ばれる領域内の新しく割り当てられたメモリ空間を指すポインタで管理および提供されます。

これで、要素の配列を実行時に問題なく動的に作成および破棄できます。要約すると、自動メモリ管理はスタックを使用し、C の動的メモリ割り当てはヒープを使用します。

ライブラリには、動的メモリ管理を担当する関数があります。

機能 目的 ma​​lloc() 要求されたサイズのメモリを割り当て、
割り当てられたスペースの最初のバイトへのポインタを返します。calloc() 配列の要素にスペースを割り当てます。要素をゼロに初期化し、メモリへのポインタを返します。realloc() 以前に割り当てられたメモリ空間のサイズを変更するために使用されます。Free() 以前に割り当てられたメモリ領域を解放または空にします。

上記の機能とそのアプリケーションについて説明しましょう

C の malloc() 関数

C の malloc() 関数は、メモリ割り当てを表します。これは、メモリのブロックを動的に割り当てるために使用される関数です。指定されたサイズのメモリ空間を予約し、メモリ位置を指す null ポインタを返します。通常、返されるポインタは void 型です。これは、C の malloc() 関数を任意のポインターに割り当てることができることを意味します。

ma​​lloc() 関数の構文:

ptr = (cast_type *) malloc (byte_size);

ここで、

ma​​lloc() の例:

Example: ptr = (int *) malloc (50)

このステートメントが正常に実行されると、50 バイトのメモリ空間が確保されます。予約済みスペースの最初のバイトのアドレスは、int 型のポインター ptr に割り当てられます。

別の例を考えてみましょう:

#include <stdlib.h>
int main(){
int *ptr;
ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */
    if (ptr != NULL) {
      *(ptr + 5) = 480; /* assign 480 to sixth integer */
      printf("Value of the 6th integer is %d",*(ptr + 5));
    }
}

出力:

Value of the 6th integer is 480

<オール>
  • sizeof(*ptr) に注意してください sizeof(int) の代わりに使用されました *ptr 宣言が後で別のデータ型に型キャストされたときに、コードをより堅牢にするため。
  • メモリが十分でない場合、割り当てが失敗することがあります。この場合、NULL ポインタを返します。したがって、NULL ポインタをチェックするコードを含める必要があります。
  • 割り当てられたメモリは連続しており、配列として扱うことができることに注意してください。括弧 [ ] を使用する代わりに、ポインター演算を使用して配列要素にアクセスできます。 + を使用して配列要素を参照することをお勧めします。インクリメント ++ または +=を使用すると、ポインターによって格納されたアドレスが変更されるためです。
  • Malloc() 関数は、文字データ型だけでなく、構造体などの複雑なデータ型でも使用できます。

    C の free() 関数

    変数のメモリは、コンパイル時に自動的に解放されます。動的メモリ割り当てでは、メモリの割り当てを明示的に解除する必要があります。そうしないと、メモリ不足エラーが発生する可能性があります。

    free() 関数は、C でメモリを解放/割り当て解除するために呼び出されます。プログラムでメモリを解放することにより、後で使用できるようになります。

    例:

    #include <stdio.h>
    int main() {
    int* ptr = malloc(10 * sizeof(*ptr));
    if (ptr != NULL){
      *(ptr + 2) = 50;
      printf("Value of the 2nd integer is %d",*(ptr + 2));
    }
    free(ptr);
    }

    出力

     Value of the 2nd integer is 50

    C の calloc() 関数

    C の calloc() 関数は、連続割り当てを表します。この関数は、複数のメモリ ブロックを割り当てるために使用されます。これは、配列や構造体などの複雑なデータ構造にメモリを割り当てるために使用される動的メモリ割り当て関数です。

    Malloc() 関数はメモリ空間の単一ブロックを割り当てるために使用され、C の calloc() はメモリ空間の複数のブロックを割り当てるために使用されます。 calloc() 関数によって割り当てられる各ブロックは同じサイズです。

    calloc() 関数の構文:

    ptr = (cast_type *) calloc (n, size);

    メモリ不足など、メモリ空間の割り当てでエラーが発生した場合は常に、null ポインターが返されます。

    calloc() の例:

    以下のプログラムは、算術数列の和を計算します。

    #include <stdio.h>
        int main() {
            int i, * ptr, sum = 0;
            ptr = calloc(10, sizeof(int));
            if (ptr == NULL) {
                printf("Error! memory not allocated.");
                exit(0);
            }
            printf("Building and calculating the sequence sum of the first 10 terms \ n ");
            for (i = 0; i < 10; ++i) { * (ptr + i) = i;
                sum += * (ptr + i);
            }
            printf("Sum = %d", sum);
            free(ptr);
            return 0;
        }

    結果:

    Building and calculating the sequence sum of the first 10 terms
    Sum = 45

    calloc() と malloc():主な違い

    以下は、C における malloc() と calloc() の主な違いです:

    一般に、calloc() 関数は、malloc() 関数よりも適切で効率的です。どちらの関数もメモリ空間を割り当てるために使用されますが、calloc() は一度に複数のブロックを割り当てることができます。毎回メモリ ブロックを要求する必要はありません。 calloc() 関数は、より大きなメモリ空間を必要とする複雑なデータ構造で使用されます。

    C の calloc() によって割り当てられたメモリ ブロックは常にゼロに初期化されますが、C の関数 malloc() では常にガベージ値が含まれます。

    C の realloc() 関数

    C realloc() の使用 関数を使用すると、既に割り当てられているメモリにさらにメモリ サイズを追加できます。元の内容はそのままに、現在のブロックを展開します。 C の realloc() は、メモリの再割り当てを表します。

    realloc() を使用して、以前に割り当てられたメモリのサイズを縮小することもできます。

    realloc() 関数の構文:

    ptr = realloc (ptr,newsize);

    上記のステートメントは、変数 newsize で指定されたサイズの新しいメモリ空間を割り当てます。関数の実行後、ポインタはメモリ ブロックの最初のバイトに戻されます。新しいサイズは、以前のメモリより大きくても小さくてもかまいません。新しく割り当てられたブロックが以前のメモリ ブロックと同じ場所を指すかどうかはわかりません。この関数は、以前のすべてのデータを新しいリージョンにコピーします。データが安全に保たれるようにします。

    realloc() の例:

    #include <stdio.h>
    int main () {
       char *ptr;
       ptr = (char *) malloc(10);
       strcpy(ptr, "Programming");
       printf(" %s,  Address = %u\n", ptr, ptr);
    
       ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new size
       strcat(ptr, " In 'C'");
       printf(" %s,  Address = %u\n", ptr, ptr);
       free(ptr);
       return 0;
    }

    C の realloc() が失敗した操作になると、null ポインターが返され、以前のデータも解放されます。

    C の動的配列

    C の動的配列を使用すると、必要に応じて要素の数を増やすことができます。 C 動的配列は、コンピュータ サイエンス アルゴリズムで広く使用されています。

    次のプログラムでは、C で動的配列を作成してサイズ変更しています

    #include <stdio.h>
        int main() {
            int * arr_dynamic = NULL;
            int elements = 2, i;
            arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocks
            for (i = 0; i < elements; i++) arr_dynamic[i] = i;
            for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
            elements = 4;
            arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elements
            printf("After realloc\n");
            for (i = 2; i < elements; i++) arr_dynamic[i] = i;
            for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
            free(arr_dynamic);
        }

    画面上の C 動的配列プログラムの結果:

     
    arr_dynamic[0]=0
    arr_dynamic[1]=1
    After realloc
    arr_dynamic[0]=0
    arr_dynamic[1]=1
    arr_dynamic[2]=2
    arr_dynamic[3]=3

    まとめ


    C言語

    1. 読み取り専用メモリ(ROM)
    2. C# の基本的な入力と出力
    3. C# を使用して
    4. C++ メモリ管理:新規および削除
    5. C プログラミングにおけるユーザー定義関数のタイプ
    6. C 動的メモリ割り当て
    7. C 標準ライブラリ関数
    8. 例による配列の C++ 動的割り当て
    9. C++ 関数とプログラム例
    10. C - 関数
    11. C - メモリ管理