
【6日でできるC言語入門】動的メモリの生成と消去
C言語でプログラムを書くとき、メモリ管理は非常に重要なテーマです。特に「動的メモリの生成と消去」は、実用的なプログラムを作る上で避けては通れない技術です。
動的メモリ管理を使うことで、必要なタイミングでメモリを確保したり、使い終わったら解放したりでき、柔軟なデータ構造や大量データの一時的な取り扱いが可能になります。
ここでは、C言語における動的メモリの基本から、具体的な使用例、メモリリークの危険性、そして実践的なサンプルプログラムまで、図や表を用いて分かりやすく解説します。

1.メモリ領域の基礎知識
1.1. C言語プログラムのメモリ領域
C言語のプログラム実行時、OSは大きく4つのメモリ領域を割り当てます。
| 番号 | 名前 | 内容 |
|---|---|---|
| ① | プログラム領域 | マシン語(実行ファイルのコード)が入る領域 |
| ② | 静的領域 | グローバル変数・static変数のための領域 |
| ③ | ヒープ領域 | 動的メモリ確保用領域(mallocなどで使用) |
| ④ | スタック領域 | 関数のローカル変数や戻りアドレス等の領域 |
メモリ領域イメージ

- プログラム領域 ・・・ 機械語プログラムが格納される。
- 静的領域 ・・・ グローバル変数/static変数が置かれる。
- ヒープ領域 ・・・ 動的にメモリを確保・消去する領域
- スタック領域 ・・・関数の実行時に使われる(ローカル変数・戻り値管理)
1.2. ヒープ領域の特徴と役割
ヒープ領域は、プログラムの実行中に動的にメモリを確保・解放できる特別な領域です。
- 必要なサイズの配列やデータを、実行時に確保できる
- 使い終わったメモリは手動で解放する必要がある
- 適切な管理を怠ると「メモリリーク」の原因になる
2.動的メモリの生成と消去
2.1. mallocとfreeの使い方
代表的なメモリ管理関数
| 関数名 | 読み方 | 主な用途と特徴 |
|---|---|---|
| malloc | マロック | 指定バイト分のメモリを動的確保 |
| calloc | キャロック | mallocと同等だが、確保領域を0初期化 |
| realloc | リアロック | 既存メモリ領域の再割当 |
| free | フリー | 動的確保したメモリの解放 |
malloc/freeの基本例
プロジェクト/ファイル名: Lesson59_1/main.c
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *nums = NULL;
int i;
// メモリの動的確保(int型5つ分)
nums = (int*)malloc(sizeof(int) * 5);
if (nums == NULL) {
printf("メモリの確保に失敗しました。\n");
return 1;
}
// 値の代入
for (i = 0; i < 5; i++) {
nums[i] = (i + 1) * 10;
}
// 結果の表示
printf("動的に確保した配列の内容:");
for (i = 0; i < 5; i++) {
printf("%d ", nums[i]);
}
printf("\n");
// メモリの解放
free(nums);
return 0;
}実行結果例
動的に確保した配列の内容:10 20 30 40 50解説
malloc関数で必要なバイト数のメモリを確保- 戻り値はvoid型(「どんなデータであるか」が定義されていません。)なので、目的の型(ここではint)にキャスト
- 確保失敗時はNULLが返るため、エラーチェックが必須
freeで解放しないと「メモリリーク」になる。
nums = (int*)malloc(sizeof(int) * 5); の意味
| 部分 | 意味 |
|---|---|
malloc(sizeof(int) * 5) | int型の大きさ(sizeof(int))×5個分のメモリ領域を動的に確保する。 |
(int*) | mallocの戻り値(void*型)を、int*型(int型へのポインタ)に型変換(キャスト)する。 |
nums = ... | 確保したメモリの先頭アドレスをnums(int型ポインタ変数)に代入する。 |
2.2. メモリリークとその防止
メモリリークとは
| 用語 | 意味 |
|---|---|
| メモリリーク | 解放忘れなどで、誰も使わないメモリが残る現象 |
- ヒープ領域のメモリはfree関数で明示的に解放が必要
- 解放しないままプログラムが続くと、使えないメモリが積み重なり、最悪プログラムやOS全体が停止することもある
メモリリークのイメージ

3.実践例:動的配列とエラー処理
キーボードから配列の長さを入力し、その長さの整数配列を動的に生成。
1以上10以下の乱数を代入し表示するプログラム(失敗時のエラー処理あり)。
プロジェクト/ファイル名: Lesson59_2/main.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int len, i;
int* arr = NULL;
printf("配列の長さを入力してください:");
scanf("%d", &len);
if (len <= 0) {
printf("配列の長さは1以上にしてください。\n");
return 0;
}
arr = (int*)malloc(sizeof(int) * len);
if (arr == NULL) {
printf("メモリの生成に失敗しました。\n");
return 1;
}
srand((unsigned int)time(NULL));
printf("生成した配列:");
for (i = 0; i < len; i++) {
arr[i] = rand() % 10 + 1;
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}「SDLチェック」を「いいえ」にして、プログラムを実行します。
実行結果例1
配列の長さを入力してください:7
生成した配列:4 1 9 2 9 5 2実行結果例2
配列の長さを入力してください:0
配列の長さは1以上にしてください。実行結果例3(極端な値で確保失敗時)
※実行環境によっては、メモリを確保できます。大量に数値が表示されるので、「Ctrl」+「c」で中断します。
配列の長さを入力してください:999999999
メモリの生成に失敗しました。まとめ
- C言語プログラムは「ヒープ領域」を使い、実行時に柔軟なメモリ確保ができる
mallocで動的確保、freeで解放を行う。エラー時のNULL判定も忘れずに- 解放忘れによるメモリリークに注意。特に長時間稼働するプログラムでは致命的になる場合がある
- 配列サイズが実行時に決まる場合など、動的メモリ管理は非常に有効
より複雑な用途や、より安全なメモリ管理をしたい場合には、callocやreallocも併せて活用すると良いでしょう。
