今回はC言語におけるメモリーの割り当てと解放について説明を行いたい。この項目の内容はC++でも行うことができるが、C++においては、これとは別にオブジェクトの割り当てと削除があり、それと混同してしまうという事態を避けたいため、今回はメモリーの確保と割り当てについて説明を行う。
メモリーの領域確保と解放
C言語においては、必要に応じてメモリーのある領域を確保・解放することができる。この場合、以下のようなコードでメモリーを確保することができる。ここでは、配列を動的に確保・解放する場合を例にあげたい。
サンプルコード
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 10
int main(void) {
int *arr = (int *)malloc(ARRAY_SIZE * sizeof(int));
for (int idx = 0; idx < ARRAY_SIZE; idx++) {
arr[idx] = idx;
printf("arr[%d] = %d\n", idx, arr[idx]);
}
free(arr);
arr = NULL;
return EXIT_SUCCESS;
}
出力例
arr[0] = 0
arr[1] = 1
arr[2] = 2
arr[3] = 3
arr[4] = 4
arr[5] = 5
arr[6] = 6
arr[7] = 7
arr[8] = 8
arr[9] = 9
解説
上記のコードはarrというint型のポインターに10個分 ((ここではARRAY_SIZEというシンボルを10に置き換えている。これについてはのちの機会に説明したい)) のint型の領域を確保した上でそのポインターを返すmalloc()
関数を呼んでいる。これによって、arrポインターは実質的に10個分のint型の配列として使えるようにしている。
その後は、for文の処理はその動的に割り当てたarrポインターが指している領域をint型の配列として扱っている。動作上も配列として動かすことができる。
その処理が終わった時に、free()
関数を呼んで確保したメモリー領域を解放して終了という形となっている。
calloc()を使う場合
なお、今回はmalloc()
関数を使ったが、calloc()
関数を使うこともできる。この場合は、「int *arr = (int *)malloc(ARRAY_SIZE * sizeof(int));
」を「int *arr = (int *)calloc(ARRAY_SIZE, sizeof(int));
」に置き換えることでできる。
malloc()
とcalloc()
の違いは、領域を確保するときに確保した領域を0で埋めるかどうかの違いのみである(malloc()
は確保するだけ、calloc()
は確保したときにその領域の内容を0で埋める)。
C言語ではメモリー領域を確保した時、不要になったら必ず解放すること
C言語では他の言語とは違い、通常の場合、malloc()
関数などでメモリーの領域を割り当てた場合、不要になった段階で必ずfree()
関数を呼んで割り当てた領域を解放しなければならない。
これは、Javaや.NET Frameworkなどで使われている、ガベージコレクションと言われる、割り当てられたメモリー領域を自動的に解放する機能がないからである。これは、不要になった段階でコード上に明示的にfree()
を呼ばないとメモリーリークを起こしてしまって、プログラム終了などで強制的に解放されない限りずっと確保されたままとなってしまい、それが溜まると最終的にメモリー不足となる原因となってしまう。従って、C言語ではこの部分は本当に気をつける必要がある。
この言語仕様はC++でも基本的には同様である。
最後に
今回はC言語におけるメモリーの確保と解放について説明した。C言語では確保されたメモリーは自動的には解放されないので、うっかり解放するのを忘れてメモリーリークを引き起こしてしまうこともあるので、是非気をつけたいところである。
ウェブマスター。本ブログでITを中心にいろいろな情報や意見などを提供しています。主にスマートフォン向けアプリやウェブアプリの開発を携わっています。ご用の方はコメントかコンタクトフォームにて。