mallocとfree
処理速度の分析が終わったので、メモリの使用量の問題の解説。 メモリの使用量が多かった場合の問題点を質問してみるが、 仮想記憶が動き出して処理速度の低下につながるといった認識は乏しい。
固定サイズ配列の問題
定番の質問として、クラスの名簿を作りたい。宣言はどう書くか?と質問してみる。 普通だったら、以下のような宣言が多い。
// 1クラス50人、名前は長くても漢字10文字程度 char name[ 50 ][ 20 ] ;
しかしながら、このプログラムでは、寿限無のような長い名前は覚えられないし、大学のような 大人数1クラスであれば、破たんする。 一方で、発生頻度が低いのに、寿限無や巨大クラスを想定した宣言をすれば、 メモリのほとんどは利用されず、効率が悪くなる。
C言語では、配列は基本固定サイズであり、以下のような変数によって、 サイズを指定することはできない。 新しいプログラム言語であれば、任意長配列も使えるが、それはプログラム言語が便利に なっただけであり、アルゴリズムと効率を学ぶこの授業であれば、その便利なプログラム言語が、 裏で何をしてくれているのか知っておく必要がある。
int n = 式 ; int a[ n ] ; // こんなことはできない。
mallocとfree
malloc は、必要に応じて指定されたbyte数のメモリを確保してくれる命令。前述のような 変数で指定される配列確保であれば、以下のようになる。
int n = 式 ; int *a = (int*)malloc( sizeof( int ) * n ) ; if ( a != NULL ) { 配列を使う処理 ; free( a ) ; }
mallocは、void*型ポインタを返すので、適切なデータのポインタに型キャストで変換してから 用いる。また、メモリ確保に失敗した場合には、NULLポインタを返すので、 if 文によるチェックが必要となる。 利用が終わったメモリ空間は、free() によって、返却し後で再利用される。
free() が適切に呼び出されず、確保したメモリを不要になった時に返却しないと、 使用されないメモリ空間が発生する。(メモリリーク) 「最後に確保したメモリから、不要になる」ような、関数の中でのみ使われる配列であれば、 alloca() なども便利である。 また、malloc+freeで確保されるヒープメモリは、プロセスの停止と共にOSに返却されるため、 処理が終わるとともに、メモリが不要となり、プロセスが終了するのであれば、 あえてfree()を書かない場合もある。しかしながら、初心者のうちは適切にfreeを呼び出す プログラム習慣を身に着けるべきであろう。
昨年度のテスト過去問題…(05/09)
- 05/09 昨年度のテスト過去問題のページの更新ができていなかったので、更新作業。ファイルは保存してあったけど、問題ページからリンクが無かった… #fnct http://tinyurl.com/d5kcxvl
この記事は、 の @TohruSaitohに掲載した #fnct タグ付き記事を、まとめたものです。