malloc/freeの使い方
メモリー利用の問題点として、C言語の固定配列サイズの 問題点を紹介し、その対応として、malloc/freeを紹介。
たとえば、複数の名前を配列に記憶する場合、
char name[ 100 ][ 20 ] ;
では、平均名前長が8文字ぐらいだと、12文字/件の無駄が 発生するし、ジュゲムのような長い名前は覚えられない。
そこで、その対応として、
char heap[ 2000 ] ; char* name[ 100 ] ;
として、
↓name[1] ↓name[3] heap: t-saitoh$tomoko$mitsuki$jugemujyugemu......$ayuka$ ↑name[0] ↑name[2]
といった、最初に巨大配列を一括して確保しておき、 データに応じて細切れにして使う手法を説明する。 こうすれば、メモリ空間は「詰めて」保存ができ、 無駄が排除できる。 でも、この領域で、途中途中のデータが不要になったら、 その隙間の管理は面倒。
malloc/free
そこで、malloc/free はこれらをうまく活用してくれる。
int size ; //サイズが入っているとする。 int* p ; // size*sizeof(int) byte のメモリを確保。 // その先頭アドレスを返してくれる。 // 型キャストののち、p に代入。 p = (int*)malloc( size * sizeof( int ) ) ; // 処理後に領域が不要になったら、freeで解放。 // 必要に応じて再利用してくれる。 free( p ) ;
ただし、通常は、malloc はメモリ確保時に、NULL を返すので、 if でチェックの必要がある。一般的な使い方は、
int size ; int* array ; scanf( "%d" , &size ) ; array = (int*)malloc( size * sizeof( int ) ) ; if ( array != NULL ) { for( int i = 0 ; i < size ; i++ ) scanf( "%d" , &array[ i ] ) ; : free( array ) ; }
ただし、free を忘れると、メモリリークが発生し、メモリの無駄な利用は、 仮想記憶の利用から、補助記憶への読み書きを発生させ、処理速度低下を 招くかもしれない。その他の内容は、以下の通り。
- 終了直前のfreeならなくてもよい。
- ネットワークプログラミングでは、子プロセス終了時に自動解放がよく使われる。
- スタック領域を使うんなら、alloca() という関数もある。
- C++なら new / delete 演算子を使う。
- ガベージコレクタのある処理系(java/C#)なら、freeは不要…
担任クラスの個人面談
担任クラスの個人面談を開始する。 本当は、手始めに10人位…と思っていたが、昨日の資源回収の疲労もあり、 「個人面談するぞ!」の話の瞬間にトーンダウン。「ひとまず今日は5人ね…」
放課後には、学生さんの都合で翌日1名になり、ちょっと拍子抜け。
個人面談の前に、昨年までの試験成績席次を表計算に書き込み、 各学生さんの成績傾向を確認しておく。 ただし面談時には、今後の目標を見据えているかを中心に、話をする。
浮動小数点の扱いと文字列の扱い
N進数表現と数値範囲の説明の続きとして、 実数型(float,double)の取り扱いについて説明する。
実数の取り扱い
実数の取り扱いとして、double/float型の内部データ保存形式の説明を行う。 (参考:IEEE 754 wikipedia.jp)
型 | 符号(s) | 指数(e) | 符号(d) | |
float | 1[bit] | 8[bit] | 23[bit] | |
double | 1[bit] | 11[bit] | 52[bit] |
double型の精度は、 より、約52*0.301=15.6桁相当といった説明。
実数型の計算のトラブル事例もいくつか紹介。
int sum , cnt ; // 合計とデータ数で、平均を表示 printf( "%f" , sum / cnt ) ; // めちゃくちゃな答が表示される。 // sum / int は、整数同士の計算で3となる。 // 小数点以下はも止まらない。 // "%f" は、浮動小数点用。第2引数に3があっても、 // 正しく表示できない。 printf( "%lf" , (double)sum / (double)cnt ) ; // 型キャスト double a , h // 三角形の底辺と高さとする。 double s ; s = (1/2) * a * h ; // 面積を計算したい // この答は常に0が表示される。 // 1/2 は、整数同士で計算され、0.5は0として扱われる。 s = 0.5 * a * h ; s = (1.0/2.0) * a * h ; // 2.0と書けば実数どうし s = a * h / 2 ; // 実数/整数は、2.0 に自動的に型拡張される
文字列の扱い
C言語における文字列の扱いを説明するために、 ASCIIコード表(JISコード表)などの説明をする。 配布資料中の例題で、10進、8進、16進変換、 文字コード間の加減算を行う。 制御文字'\n','\r','\f'などを、タイプライタの動き を例にしながら、説明を行う。
Geocodingなど
Perlで地名から緯度経度を簡単に求めるのに使えそう
- http://www.geocoding.jp/api/
- XML::Simple
Quad Core マシンがメモリエラー
研究費で Quad Core のハイパワー環境として導入した PowerEdge T105 であるが、 OS のインストールから手を焼いた。ひとまずOSが動きだしたのはいいんだけど、 今度は、"aptitude safe-upgrade" あたりを実行しようとすると再起動がかかってしまう。 ネットワークを使う仕事でエラーがでるのかと思い、オンボードEther のドライバ tg3 の ドライバの最新をひろって入れて安定…かと思いきや、やっぱり勝手に再起動。
不安になってきたけど、BIOSの画面で"エラーレポート"の機能に気づき、 LOGを確認すると、"Unrecoverble ECC Memory Error DIMM2,2"が立て続けに 記録されていた。 メモリの初期不良品をつかんでしまったかと思って、ブルーになるが、状況確認のために メモリのスロットを入れ替える。その結果、ちょいと処理をさせても安定している。 しかし、いつ再発するかわからないので、「負荷試験」がわりに、 必要ないけどカーネル再構築とパッケージの追加インストールを行う。 再構築はまだ実行中だけど、過負荷に耐えている。 この雰囲気は、「メモリの接触不良によるECCエラーで、スロット入れ替えにより、 接触不良が改善された」という様子。
ハノイの塔の帰納法による証明とメモリ利用の問題提起
ハノイの塔の処理回数の証明
前回授業のハノイの塔のルールの説明を受け、 実際にハノイの塔の処理回数の再帰方程式を示す。 そして実際にその証明ということで、数学的帰納法を用いて証明を行う。
処理速度のオーダの一般例として、 の事例として、クイックソートなどの例を示し、説明のしやすい マージソートについて、再帰方程式を示す。 次に代入法により、その式の一般解を示す。
メモリ利用の問題提起
例として、名前と電話番号のデータベースを作るというテーマとして、 これに必要とするデータ構造の宣言を示し、その問題点を示す。
#define DATA_SIZE 100 #define NAME_SIZE 10 #define TEL_SIZE 10 char name[ DATA_SIZE ][ NAME_SIZE ] ; char tel[ DATA_SIZE ][ TEL_SIZE ] ;
しかし、DATA_SIZE は、1クラス50人ではなく、学年=200人、学校=1000人かもしれない。 TEL_SIZE は、12-3456 でなく、携帯電話 090-1234-5678 の16文字かもしれない。 "0033"をつけるかもしれない、"内線番号"がつくかもしれない、"国際電話で国別コード"がつくかもしれない。 NAME_SIZE も、漢字8文字=16byteかもしれない、 寿限無 みたいな名前だったら、漢字約100文字=200byte にするのか? 最初から、こういうめったにない事例に応じて、*_SIZE を巨大にするのは、メモリの無駄。 かといって、
int x ; char name[ x ] ; // C言語では、配列サイズは定数しか使えない
こういう点で、データサイズが任意というのは、いかにプログラムで扱いにくいのかを説明する。
複素数をテーマにしたレポート
オブジェクト指向プログラミングの、具体的な処理によるレポート課題 ということで、例年どおりの複素数の取り扱いのプログラムの説明と 演習を行った。
レポート1(複素数の加減乗除)
授業中に示した上記の2つのプログラムをベースに、 記載されていない減算・除算のプログラムを作成し、レポートを作成する。 レポートには、下記のものを記載すること。
- プログラムリスト
- プログラムへの説明
- 動作確認の結果
- プログラムより理解できること。
実際にプログラムを書いてみて分かった問題点など…
unixなんだけど、Mac OS Xは癖が強い
今まで、ずーっと避けていたMac OS/X だけど、 MacBookを使い始めて、いろいろと試している。 手始めとしてWebアプリ開発の実験環境とするために、 MAMP(Mac+Apache+MySQL+PHP)によるWebサーバ環境を動かす。
しかし、Linux環境で動かしていたスクリプトとのPATHの違いを 吸収するために、設定を色々と変更するが unix とはいえ、 サーバ設定の定番がことごとく違う。
/homeがautomounterに?
/homeの配下が空っぽだったので、"ln -sf /Users/username /home/username"を しようとすると、拒否される。"df"で確認すると、automounter に 使われている。 モバイル的に使うノートパソコンじゃ NIS やらを使う予定もないので、 /etc/auto_master の "/home"の設定をコメントアウト。
/etc/init.dが無い…
automounterの設定を触ったので、"/etc/init.d/autofs restart" らしきことを やろうと思ったが、init.d も rc.local も無い。 うーむ、/System/Library/StartupItems or /Library/StartupItems あたりを 記述するらしいのだが、"ちょっとくらいPOSIXといった普通を取り入れてよ…"と ぼやきたくなる…
高校でも専攻科卒で大学編入
ニュースサイトの情報によると、 高校「専攻科」卒業生、大学編入可能に 文科省が方針 を示したそうだ。 元々、高専の専攻科でも人数の少なさから認知度は高くはないけど、 高校でも専攻科が設置されていたんだ…んで、大学に編入ができるようになるのか…. 高専卒の大学編入組にとっては、競争相手の登場で、狭き門になるのかな…