>> C言語入門トップに戻る
今回はメモリの動的確保について説明します。
今までは変数をただ宣言することで、変数(メモリ)を確保していました。
ですが、これだとユーザの要求に応じたサイズのメモリが必要になったり、
した時にはあらかじめ大きめに確保しておくなどするしか方法がありません。
状況に応じて、自由な大きさのメモリを確保できた方が良いプログラムが書けますよね?
そんなときには、メモリの動的確保という方法があります。
まずは下記のコードを見てください。
これを実行すると、0,1,2,3、と縦に並んで表示されます。
まずメモリを動的確保するには、専用の関数が必要になります。
malloc関数です。stdlib.hのヘッダーファイルをインクルードする必要があります。
malloc関数の第一引数には確保するメモリのサイズを指定します。
今回はint型のメモリを4つ確保しようとしています。
int型のサイズは4バイトなので4×4の16バイト確保しているわけです。
int型のサイズを4バイトなのでそのまま、4×4と直接書いても構わないのですが、
コンパイラなどが違うと必ずしも4バイトでないときがあるので、
そのときには自動的に型のサイズを計算しくれる演算子を使います。
それが、sizeof演算子です。
この演算子の第一引数にその型の名前を書くと、その型のサイズを返してくれます。
これで、malloc関数の第一引数のサイズ指定は出来ました。
次にmalloc関数の左にある、
(int*)というものがあります。
これは、キャストと言って、型の変換をするためのものです。
malloc関数を実行すると、void型のポインタが返ってきます。
さらに、メモリを動的確保したときには、通常はポインタで受け取ります。
今回はint型のメモリを4つ分確保したので、int型のポインタで受け取るというわけですね。
ですが、malloc関数が返すポインタはvoid型、受け取るほうのポインタはint型なのでこのままでは受け取れずに、
コンパイルエラーが出てしまいます。
それを解決するために、キャストをしてあげてるのです。
キャストの書き方は
(型)
と書くだけです。
今回はint型のポインタの変数に代入するので、int型のポインタ型にキャストします。
ですので、(int*)となっているわけです。
わかりましたでしょうか?
その後は、ポインタを受け取ったので、その確保したメモリの領域を自由に使えます。
受け取ったポインタは、確保したメモリの先頭ポインタが入っています。
先頭ポインタと聞いて思い出すことありますよね?
そう配列です。
つまり配列としてint型の変数が4つ確保されたことと同じということです。
後は、添字をつけて配列のようにアクセスするだけです。
最後にforループ文で0~3までiの値を変化させて、point[]の添字を変えながら、
各要素にアクセスし、printfで表示させてるだけです。
で、最後の最後に必要なのが、メモリの解放です。
今まで普通に変数を宣言していたときは、自動的に解放処理が行われていましたが、
自分で動的確保した場合は自分で解放処理もしないといけません。
メモリの解放には、free関数を使います。
この関数の第一引数に、malloc関数を実行したときに返されたポインタを指定します。
今回のコードだと、point変数ですね。
これを引数に指定して、free関数を実行します。
これでメモリの解放処理は終わりで、他にやることはありません。
これがメモリの動的確保の仕組みになります。
理解できましたでしょうか?
今日勉強したばっかりなので、どういう時に使えるのかまだよくわからない人がたくさんだと思いますが、
そのうちに高度なプログラミングをしていく上で、絶対に必要になるスキルですので、頑張って覚えておきましょう。
>> 【typedefについて】に進む
>> C言語入門トップに戻る
メモリの動的確保
今までは変数をただ宣言することで、変数(メモリ)を確保していました。
ですが、これだとユーザの要求に応じたサイズのメモリが必要になったり、
した時にはあらかじめ大きめに確保しておくなどするしか方法がありません。
状況に応じて、自由な大きさのメモリを確保できた方が良いプログラムが書けますよね?
そんなときには、メモリの動的確保という方法があります。
まずは下記のコードを見てください。
#include <stdlib.h> #include <stdio.h> int main(void){ int *point; //4バイト×4のメモリを確保 point=(int*)malloc(4*sizeof(int)); //代入 point[0]=0; point[1]=1; point[2]=2; point[3]=3; //表示 for(int i=0;i<4;++i){ printf("%d\n",point[i]); } //メモリを解放 free(point); return 0; }
これを実行すると、0,1,2,3、と縦に並んで表示されます。
まずメモリを動的確保するには、専用の関数が必要になります。
malloc関数です。stdlib.hのヘッダーファイルをインクルードする必要があります。
malloc関数の第一引数には確保するメモリのサイズを指定します。
今回はint型のメモリを4つ確保しようとしています。
int型のサイズは4バイトなので4×4の16バイト確保しているわけです。
int型のサイズを4バイトなのでそのまま、4×4と直接書いても構わないのですが、
コンパイラなどが違うと必ずしも4バイトでないときがあるので、
そのときには自動的に型のサイズを計算しくれる演算子を使います。
それが、sizeof演算子です。
この演算子の第一引数にその型の名前を書くと、その型のサイズを返してくれます。
これで、malloc関数の第一引数のサイズ指定は出来ました。
次にmalloc関数の左にある、
(int*)というものがあります。
これは、キャストと言って、型の変換をするためのものです。
malloc関数を実行すると、void型のポインタが返ってきます。
さらに、メモリを動的確保したときには、通常はポインタで受け取ります。
今回はint型のメモリを4つ分確保したので、int型のポインタで受け取るというわけですね。
ですが、malloc関数が返すポインタはvoid型、受け取るほうのポインタはint型なのでこのままでは受け取れずに、
コンパイルエラーが出てしまいます。
それを解決するために、キャストをしてあげてるのです。
キャストの書き方は
(型)
と書くだけです。
今回はint型のポインタの変数に代入するので、int型のポインタ型にキャストします。
ですので、(int*)となっているわけです。
わかりましたでしょうか?
その後は、ポインタを受け取ったので、その確保したメモリの領域を自由に使えます。
受け取ったポインタは、確保したメモリの先頭ポインタが入っています。
先頭ポインタと聞いて思い出すことありますよね?
そう配列です。
つまり配列としてint型の変数が4つ確保されたことと同じということです。
後は、添字をつけて配列のようにアクセスするだけです。
最後にforループ文で0~3までiの値を変化させて、point[]の添字を変えながら、
各要素にアクセスし、printfで表示させてるだけです。
で、最後の最後に必要なのが、メモリの解放です。
今まで普通に変数を宣言していたときは、自動的に解放処理が行われていましたが、
自分で動的確保した場合は自分で解放処理もしないといけません。
メモリの解放には、free関数を使います。
この関数の第一引数に、malloc関数を実行したときに返されたポインタを指定します。
今回のコードだと、point変数ですね。
これを引数に指定して、free関数を実行します。
これでメモリの解放処理は終わりで、他にやることはありません。
これがメモリの動的確保の仕組みになります。
理解できましたでしょうか?
今日勉強したばっかりなので、どういう時に使えるのかまだよくわからない人がたくさんだと思いますが、
そのうちに高度なプログラミングをしていく上で、絶対に必要になるスキルですので、頑張って覚えておきましょう。
>> 【typedefについて】に進む
>> C言語入門トップに戻る