C 基本講座

関数で動的にメモリを確保する

LinkedInラーニングの無料トライアルを今すぐ試そう

無料で視聴する すべての加入プランを見る
このレッスンでは、標準ライブラリ関数を使って、自由にメモリ領域を確保する方法について説明します。
講師:
09:17

字幕

このレッスンでは標準ライブラリ関数を使って自由にメモリ領域を確保する方法を説明します。配列は宣言時に大きさが決まります。そのため、ある程度の無駄を承知で大きさを確保する必要があります。けれども標準ライブラリ関数を使うとプログラムの実行中に動的に必要なメモリ領域を確保することができます。動的にメモリを確保する一番一般的な標準ライブラリ関数はmalloc です。malloc はキープ領域というメモリ領域から引数で指定したサイズのブロックを割り当て、確保した領域のポインタを返却します。malloc を使用するのにはstdlib.h の include が必要です。例えば int サイズの100 個の領域を確保するのにはこのように記述します。malloc の引数に確保したいメモリのバイトサイズを記述します。今変数 n は 100 が代入されているので100 に int サイズを掛けて引数に指定しています。malloc は領域確保に成功した場合には確保したメモリブロックを指すポインタを返します。この返却されるポインタの型はvoid アスターでどのような型のポインタでも指定できる汎用ポインタ型です。 malloc 関数で返却されるポインタの型はmalloc を使用する場所ごとに異なります。そのため、型の指定ができません。よって、この void アスターでどのような型にするか後で決めてください。とりあえずポインタを返しますよと宣言するのです。しかし、使用するときにはこの使用例のように本来の目的の型でキャストしてやるべきでしょう。また、malloc はメモリ確保に失敗した場合にはNULL という空ポインタを返却します。この NULL はどこも指していない特殊なポインタで本来返却されるはずのポインタがなんらかの事情で返却されない時などに用いられます。ですから NULL が返却された場合にはこのようにエラー処理をしてください。尚、malloc 関数で確保したメモリは使用後必ずfree で解放してください。実際にはプログラムが終了するときに確保したメモリも解放されるのでこのプログラムのように短いプログラムではすぐに終了するのでfree は不要です。けれどもプログラムの中には365 日、24 時間動き続けるものも存在します。そのようなプログラムで動的に確保したメモリをfree しないで malloc を続けて呼んでいると使用可能なメモリ領域がなくなり、メモリリークが発生します。 メモリリークが発生すると当然ですが、プログラムは動くことができなくなってしまいます。ですから短いプログラムでも使い終わったメモリはfree 関数で解放する癖をつけておきましょう。このままではちゃんと確保したメモリが使えるかどうかわからないので少しプログラムを書き換えてみましょう。まずこの n を scanf と入力して自由に確保するサイズを変えられるようにします。尚 Windows 版の Eclipse ではscanf の前に printf があるとコンソールビューからの入力がうまく実行できません。そのため、この setvbuf 関数でbuf を使わないようにしています。次に確保した領域にカウンタ変数 +1 の値を代入しています。そしてちゃんと代入されているかを表示して確認しています。尚、この?とコロンは条件演算子でi を 20 で割った余りが19 と等しければ改行しています。つまり 20 出力するたびに改行しているわけです。では実行してみましょう。このように 100 を代入すれば100 個の領域が使えるようになりました。200 を入力すれば200 の領域が使えるようになっています。このように n の値に応じてメモリが使えるようになっていることがわかりますね。 尚、この角括弧は配列添え演算子と呼ばれこの演算子を使うとポインタを配列のように扱うことができます。ポインタ表記で*(buf+i) と記述しても構いません。この malloc で確保した領域は中に何が入っているかわからない不定値です。しかし、calloc という標準ライブラリ関数を使うと確保したブロックを0で初期化してくれます。malloc の代わりにcalloc を使ってみましょう。calloc は引数に要素数と各要素のサイズを渡します。では確保した領域が本当に0で初期化されているか値を代入している箇所をコメントアウトして確認してみましょう。100 と入力してみるとこのように 100 個の領域が0でクリアされていることが確認できます。このコメントは元に戻しておきます。malloc や calloc で確保した領域がプログラム実行中に足りなくなる場合も考えられますね。そのような場合にはrealloc 関数を使うと確保した領域のサイズを変更することができます。realloc の引数にはすでに確保したキープメモリへのポインタと変更したいメモリのバイトサイズを指定します。ここでは n の2倍を指定しています。 メモリの確保に失敗した場合にはNULL を返すのでこのようにエラー処理をしてください。realloc の返却値は一時作業用の変数にとり、そして NULL でないことを確認してから元の変数に代入するようにしてください。この時、realloc の引数として指定したもともとの buf とrealloc が返したこの tmp のアドレスが変化した場合には buf を指す領域は自動的に解放されるのでfree の必要はありません。しかし、エラー時にはfree されないのでこのように自分で free してください。realloc は古いメモリブロックにあったデータは可能な限り新しいメモリブロックにコピーします。それを確認してみましょう。このように realloc で後から確保した領域に10 を代入してみます。そしてすべての領域を表示してみます。例えば 50 を入力すると、このように最初は1から 50 までを表示しますが、後から拡張された分については10 が表示されます。尚 realloc の多様はメモリブロックの断片化を招きやすくなりますので事前に大きめのメモリサイズを確保し、realloc の多様は避けた方が良いでしょう。 このレッスンでは標準ライブラリ関数を使って自由にメモリ領域を確保する方法について説明しました。

C 基本講座

C言語はUNIXというOSを記述するために開発されたプログラミング言語で、組み込みシステムの開発を中心に今も使われています。このコースでは簡単なプログラムを作成しながら、C言語の基本的な文法を学びます。データ型や制御文などの基礎的な文法からポインタや構造体といったC言語の特徴的な内容まで幅広く取り上げます。よく使われる標準ライブラリ関数も数多く紹介します。

5時間45分 (60 ビデオ)
現在、カスタマーレビューはありません…
ソフトウェア・トピック
プラン加入者限定
発売日:2017年11月05日

このコースは、「オンデマンド」でご利用可能であり、ダウンロードすることもオンラインで見ることもできます。

ダウンロードすると、オフラインでコースを使用し、豊富なインターフェースをフルに活用できます。複数のデバイスを使用したり、 一度に全コースをダウンロードしたくない場合は、アカントにログインして、ストリーミング・ビデオとしてコースのレッスンを視聴してください。

ビデオトレーニングをお楽しみいただけますように! お問い合わせは、cs-jp@lynda.com宛までご連絡ください。