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 での動的メモリ割り当て
- C の malloc() 関数
- C の free() 関数
- C の calloc() 関数
- calloc() と malloc():主な違い
- C の realloc() 関数
- 動的配列
C での動的メモリ割り当て
動的メモリ割り当て プログラミングのニーズに応じてメモリを手動で割り当ておよび解放することです。動的メモリは、ヒープと呼ばれる領域内の新しく割り当てられたメモリ空間を指すポインタで管理および提供されます。
これで、要素の配列を実行時に問題なく動的に作成および破棄できます。要約すると、自動メモリ管理はスタックを使用し、C の動的メモリ割り当てはヒープを使用します。
割り当てられたスペースの最初のバイトへのポインタを返します。calloc() 配列の要素にスペースを割り当てます。要素をゼロに初期化し、メモリへのポインタを返します。realloc() 以前に割り当てられたメモリ空間のサイズを変更するために使用されます。Free() 以前に割り当てられたメモリ領域を解放または空にします。
上記の機能とそのアプリケーションについて説明しましょう
C の malloc() 関数
C の malloc() 関数は、メモリ割り当てを表します。これは、メモリのブロックを動的に割り当てるために使用される関数です。指定されたサイズのメモリ空間を予約し、メモリ位置を指す null ポインタを返します。通常、返されるポインタは void 型です。これは、C の malloc() 関数を任意のポインターに割り当てることができることを意味します。
malloc() 関数の構文:
ptr = (cast_type *) malloc (byte_size);
ここで、
- ptr は cast_type のポインタです。
- C の malloc() 関数は、byte_size の割り当てられたメモリへのポインタを返します。
malloc() の例:
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
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);
- 上記のステートメントは、同じサイズの n 個のメモリ ブロックを割り当てるために使用されます。
- メモリ空間が割り当てられた後、すべてのバイトがゼロに初期化されます。
- 割り当てられたメモリ空間の最初のバイトに現在あるポインタが返されます。
メモリ不足など、メモリ空間の割り当てでエラーが発生した場合は常に、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 動的メモリ割り当てでは、実行時にメモリが割り当てられます。
- 動的メモリ割り当てにより、サイズが柔軟で、プログラム内でいつでも変更できる文字列と配列を操作できます。
- 特定の構造がどれだけのメモリを占有するかわからない場合に必要です。
- C の Malloc() は動的メモリ割り当て関数で、特定のサイズのメモリ ブロックをガベージ値に初期化するメモリ割り当てを表します
- C の Calloc() は、0 に初期化された複数のメモリ ブロックを一度に割り当てる連続したメモリ割り当て関数です
- C の Realloc() は、指定されたサイズに従ってメモリを再割り当てするために使用されます。
- Free() 関数は、動的に割り当てられたメモリをクリアするために使用されます。
C言語