C/C++のmalloc()とfree()の仕組みを徹底解説!動的メモリ確保と解放の基本
C言語やC++では、プログラムの実行時に必要なメモリを動的に確保・解放できます。その中核を担うのが標準ライブラリの malloc() と free() です。この記事では、両関数の基本的な仕組み、書式、そして具体的な使用例をわかりやすく解説します。
malloc()とは?
malloc() は、指定されたサイズ(バイト数)のメモリをヒープ領域に動的に確保し、確保したメモリの先頭バイトへのポインタを返す関数です。メモリの確保に失敗した場合には、NULLポインタが返されます。
C言語における malloc() の基本構文は以下のとおりです。
pointer_name = (cast-type*) malloc(size);
各要素の意味は次のとおりです。
pointer_name − ポインタに付ける任意の名前です。
cast-type −
malloc()が確保したメモリを、どのデータ型のポインタとして扱うかを指定するキャスト先の型です。size − 確保するメモリのサイズ(バイト単位)です。通常は
sizeof演算子と組み合わせて指定します。
malloc()の使用例
以下は、C言語で malloc() を使って int 型4個分のメモリを確保し、配列のように扱うサンプルプログラムです。
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 4, i, *p, s = 0;
p = (int*) malloc(n * sizeof(int));
if(p == NULL) {
printf("\nError! memory not allocated.");
exit(0);
}
printf("\nEnter elements of array : ");
for(i = 0; i < n; ++i) {
scanf("%d", p + i);
s += *(p + i);
}
printf("\nSum : %d", s);
return 0;
}
実行結果
Enter elements of array : 32 23 21 8 Sum : 84
この例では、malloc(n * sizeof(int)) によって int 型4個分の連続したメモリ領域を確保しています。確保後にNULLチェックを行い、失敗していた場合はプログラムを終了するのが安全な作法です。
free()とは?
free() は、malloc() などで動的に確保したメモリを解放する関数です。メモリを解放しても、ポインタ変数自体の値は変わりません。つまり、ポインタは引き続き同じメモリ位置を指し続けます(いわゆる「ダングリングポインタ」の状態になるため、解放後のアクセスには注意が必要です)。
C言語における free() の基本構文は以下のとおりです。
void free(void *pointer_name);
各要素の意味は次のとおりです。
pointer_name − 解放対象のメモリを指すポインタの名前です。
free()の使用例
先ほどのプログラムに free() を追加した例を示します。使い終わったメモリを明示的に解放することで、メモリリークを防げます。
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 4, i, *p, s = 0;
p = (int*) malloc(n * sizeof(int));
if(p == NULL) {
printf("\nError! memory not allocated.");
exit(0);
}
printf("\nEnter elements of array : ");
for(i = 0; i < n; ++i) {
scanf("%d", p + i);
s += *(p + i);
}
printf("\nSum : %d", s);
free(p);
return 0;
}
実行結果
Enter elements of array : 32 23 21 28 Sum : 104
まとめ
malloc() は実行時に必要なサイズのメモリをヒープから確保し、free() はそのメモリをシステムに返却する関数です。両者は必ずペアで使用するのが基本で、確保したメモリを解放し忘れるとメモリリークの原因となります。また、malloc() の戻り値は必ずNULLチェックを行い、安全にメモリを扱うことを心がけましょう。
-
【初心者向け】C++の例外処理の仕組みを徹底解説!try・catch・throwの基本から独自例外の作成まで
C++における例外処理(Exception Handling)とは、プログラムの実行中に発生するエラー(ランタイムエラー)を適切に処理するための仕組みです。例外とは、実行時に送出されるイベントのことを指し、C++ではすべての標準例外が std::exception クラスを基底クラスとして定義されています。 もし例外を捕捉しなければ、プログラムは例外メッセージを出力した後に異常終了してしまいます。例外はハンドリング可能なランタイムエラーであり、適切に処理することでプログラムの堅牢性を大きく向上させることができます。 標準例外クラスの階層構造 C++標準では、例外は <exception&
-
C++で組み合わせと順列を計算する方法をわかりやすく解説
組み合わせと順列とは組み合わせ(Combination)と順列(Permutation)は、数学の一分野である組合せ論(Combinatorics)に属する概念です。順列とは、n個の要素の中から、1つずつ・いくつかずつ・あるいはすべてを一度に取り出して並べるときの、異なる並び方の総数のことです。並べる順序が結果に影響する点が特徴です。一方、組み合わせとは、同じくn個の要素から1つずつ・いくつかずつ・すべてを取り出して選ぶときの、異なる選び方の総数です。順序は考慮されないため、順列よりも数が少なくなります。計算式順列の数n個の要素全体からr個の要素を並べるときの順列の数は、次の公式で求められます