返り値は、使う用途に応じて型キャストが必要である。確保したメモリは、その関数が終了すると、その領域は使えなくなる。確保したメモリが、最初に不要となる...ような使い方でしか使えない。動的メモリ確保(malloc()とfreelist)2019年1月15日C言語では、動的メモリ領域をどのように管理していくのか解説する。局所変数とスタック局所変数は、関数に入った時に作られるメモリ領域であり、関数の処理を抜けると自動的に開放されるデータ領域である。関数の中で関数が呼び出されると、スタックには戻り番地情報を保存し、関数に移動する。最初の処理で局所変数領域が確保され、関数を終えると局所変数は開放される。Out)ことから、スタック上に保存される。;」を実行したら、bar()のxを書き換えられるかも...動的メモリ領域とフリーリスト動的なメモリ領域(ヒープ領域)は、malloc()関数で処理用のメモリを借り、free()関数で使わなくなったメモリを返却する。呼び出されたときに再利用を行う。この再利用するメモリ領域は、簡単に扱えるようにリスト構造にして保存する。メモリサイズが一定として説明を行う。任意サイズのメモリ確保の場合この図の一番下の赤部分は、次のメモリブロックへのポインタとブロックサイズの大きさが20byteの場合の例。中にあれば、それを使う。いいサイズが無い場合は、それより大きいメモリブロックの後半を切り分けて、貸し出す。この例の最後の処理では、20byte,60byte,40byte,50byteが併合された例。併合後のブロックサイズは、すこしいい加減に書いてある。繰り返すと、小さなメモリブロックばかりになってしまい、大きいメモリのmalloc()ができなくなる。返却される際には、隣り合うメモリブロックと併合できるかを確認し、大きなメモリブロックになるような処理を行う。隣り合うメモリブロックが併合できるかの判定が簡単になるように、free_listにつなぐ際は、次のメモリブロックへのポインタは、昇順となるように並べる。一般的には、上記のようにmalloc(),free()を行うが(K&Rのmallocアルゴリズム)、mallocのサイズが小さい場合には併合処理などは隣接確認などが手間がかかる。そこで、最初に説明した一定サイズのmalloc()の手法で、8byte専用のfreelist,16byte専用のfreelist,32byte専用のfreelistのように2Nbyteのfreelistで管理する。10byteといった中途半端なサイズの時は、それより大きい16byteのfreelistを使う。繰り返すと、最悪、以下の図の様に、使用中領域(赤)とfreeされた未使用領域(黒)が交互に並ぶ状態が発生するかもしれない。この場合、全体の未使用領域の合計では十分なサイズでも、小さなメモリブロックばかりとなって、大きなメモリブロックを要求されても十分な大きさのメモリが見つからない状態が発生する場合がある。この状態をヒープメモリの断片化といい、使用しづらい小さなメモリブロックはヒープホールと呼ばれる。断片化というと、OSではハードディスクの断片化(フラグメンテーション)を思い浮かべるかもしれない。ハードディスクの断片化とは、ファイル領域の割り当てとファイルの削除を繰り返すことで、ファイルのセクタが不連続となり、アクセス効率が悪くなる現象。OSによっては、ファイル実体の位置を動かすことで断片化を改善できる。以下の図のようにフラグメンテーションを防ぐための実体の移動を行う最適化はデフラグと呼ばれる。上記の図では、上の青の図が断片化が発生している事例で、a1→a2,a2→a3の時にヘッド移動(シーク時間)が発生する。下の赤の図のように、デフラグ処理を施すことでシーク時間が減らせる。前回の授業で説明していたような、必要に応じて確保するメモリは、動的メモリと呼ばれる。動的メモリも、局所変数やalloca()を用いたスタック領域と、malloc()とfree()を使うヒープメモリ領域に分類される。領域確保しながら使う場合、1次元配列や2次元配列を作る場合、色々な確保の方法がある。;2次元配列2次元配列の扱いでも、注意が必要。;レポート課題メモリの動的確保の理解のために、自分の理解度に応じて以下のプログラムのいずれかを作成せよ。プログラム作成時には、配列サイズは未定で、プログラム起動時に配列サイズを入力するものとする。固定長の名前で、人数が不明。複素数のデータで、データ件数が不明。名前と電話番号のデータで、データ件数が不明。このような状況で、データを入力し、検索などの処理を通して自分のプログラムが正しく動くことを検証せよ。レポートには、プログラムリスト、プログラムの説明、動作確認した結果、考察を記載すること。前回の講義での、「長いかもしれない名前」を覚える処理は、最悪の場合をどう扱うかでメモリのムダが発生する。ここで、前回講義で説明した、大きな配列を少しづつ分けて使う処理を考える。ポインタを後ろに移動していく。スタックこの貸し出す度に、末尾の場所をずらす方式にスタックがある。このデータ管理方法は、最後に呼び出した関数が最初に終了することから、関数の戻り番地の保存や、最後に確保した局所変数が最初に不要となることから、局所変数の管理に利用されている。C言語では、配列サイズに変数を使えない。スタック領域を使用するため、数MBといった巨大なデータを確保するのには使えない。この領域は、スタックのように末尾だけを覚えておけばいいので、管理が簡単である。一方で、関数の局所変数として確保して、「この場所を使ってこの計算してね」的な使い方をしなければならない。「この場所を返すから後は自由に使って」的な使い方はできない。使うような処理は、スタックのように「最後に確保したものが最初に不要となる」という状況でしか使えない。