電子情報Webサーバ、SSLに対応
学術研究機関を対象とした無償のSSLキー発行サービスを利用して、 学科WebサーバをSSL対応にしました。 先日より学内での動作を確認し、本日より高専FireWall部の、 内向けProxyサーバでも同様の鍵の登録を行い、 SSL(https)での接続ができるようになりました。
このBLOGのようなメンテナンスの学外からの操作や、 学科メールサーバの学外からの操作の時に、 「オレオレ認証キー信用するの?」の警告無しで、 安心して使えるようになりました。
第21回高専プロコン応募(校内審査)
今年度のプロコンのテーマが発表され、 創造工学およびIT研究会より応募があり、 学内審査の結果、以下の5チームを書類審査に応募することになりました。
- 課題:「ブレイン・スペース~新感覚電脳補完~」(4EI:小林貴、3EI多田)
- 課題:「Thlowで行こう!」(4EI:川口、片岡、出口、月田、中川、笠嶋)
- 自由:「貼ろうわーるど~地球を創って転がそう~」(4EI:飯田、井上、島田、関、山下)
- 自由:「砂であそぼう!!~砂で描くメッセージ~」(4EI:本山、久世、小林成、森、ツェンデ )
- 競技:「4セルくれ~2セルで十分ですよ~」(4EI:戸嶋、直江、八田、原、山田)
UPKIオープンドメイン証明のProxyへの登録
先日、UPKIオープンドメイン証明の鍵作成や、登録作業を行ったが、 最終段階として、学科WebサーバはFireWallの内側で、カギは 内向けProxyについても登録の必要があった。 内部的に動作の確認の後の運用開始の必要性があり、 内部的に動作確認が取れた。 最終的に情報処理センターにて、作業が行われたみたいで、 この学科サーバも、https接続で「オレオレ証明書、信じる?」的な、 警告が出ていたけれど、無事、警告無しで接続できることが確認できた。 めでたし、めでたし….
2010年6月6日(第167回)
特別企画 ザ・ルーズドックスの永田さん、古市さんが出演!!
学生時代の思い出を中心に、たーっぷりお話いただきました。(収録)
収録後、番組に対するメッセージをもらいました!!
リスト構造の導入
mallocによる動的メモリ確保の説明が終わったので、 次のステップとしてリスト構造の話を行う。 アパートの回覧板の管理をイメージしてもらいながら、 次のデータの場所を管理する方法を説明。
int top = 3 ; struct List { int data ; int next ; } list[ 10 ] = { { 5 , 4 } , //0 { 4 , 0 } , //1 { 2 , 1 } , //2 { 1 , 2 } , // 3 { 8 ,-1 } , //4 } ; for( int i = top ; i >= 0 ; i = list[ i ].next ) printf( "%d" , list[ i ].data ) ; // 昇順に表示される。
次に、この次のデータの「配列添え字」ではなく、 データ1件毎にメモリを確保し、次のメモリの番地をつなぐために、 以下のような方法をとる。
struct List { int data ; struct List* next ; } ; // 理解してもらうためにあえて面倒な処理をそのまま書く struct List* top ; top = (struct List*)malloc( sizeof( struct List ) ) ; top->data = 1 ; top->next = (struct List*)malloc( sizeof( struct List ) ) ; top->next->data = 2 ; top->next->next = (struct List*)malloc( sizeof( struct List ) ) ; top->next->next->data = 3 ; top->next->next->next = NULL ; // もう少し簡単に struct List* cons( int x , struct List*n ) { struct List* ans ; if ( (ans = (struct List*)malloc(sizeof(struct List))) != NULL ) { ans->data = x ; ans->next = n ; } return ans ; } struct List* top = cons( 1 , cons( 2 , cons( 3 , NULL ) ) ) ;
この例で、データがいかに作られるのか説明の後、そのデータを扱うプログラムとして、 リストの件数・合計・最大値を求めるプログラムを、考えてもらったり、再帰呼び出しで 書いてもらう。
// 例:リストの件数 int count( struct List*p ) { for( int c = 0 ; p != NULL ; p = p->next ) c++ ; return c ; } // ループを使わずに再帰で合計 int sum( struct List*p ) { if ( p == NULL ) return 0 ; else return p->data + sum( p->next ) ; }
授業後にテストの質問として、過去問題の質問に答える。 昨年度の出題のネタだけど、ポインタと動的確保したデータのイメージを 確認する出題をしているが、詳しく授業でまだ説明していない。 来週は、テスト前対策ということで、説明を加えようか…
// 以下のようなメモリ確保を行った場合の、データの格納イメージは? struct Complex { double re , im ; } ; struct Complex data1[ 2 ] ; struct Complex* data2 = (struct Complex*)malloc( sizeof( struct Complex ) * 2 ) ; struct Complex* data3[ 2 ] = { (struct Complex*)malloc( sizeof( struct Complex ) ) , (struct Complex*)malloc( sizeof( struct Complex ) ) , } ; struct Complex** data4 ; = (struct Complex**)malloc( sizeof( struct Complex* ) * 2 ) ; data4[0] = (struct Complex*)malloc( sizeof( struct Complex ) ) ; data4[1] = (struct Complex*)malloc( sizeof( struct Complex ) ) ;
高等専門学校機関別認証評価の説明会参加
高専や大学では、学校運営の適切さを評価するための機構として、 認証評価というシステムがあり、5年周期で大学評価学位授与機構によるチェックを受ける。 本高専では、前回の受審から5年ということで、平成24年に2回目の審査の予定となっている。
前回の審査では、JABEE委員・認証評価委員ということで、受審の資料作りに参加していたことから、次回審査で経験を活かすという意味で、再び認証評価委員となる予定…(T_T; ということで、 説明会に参加した。東京で6/1(火)13:00-17:00の説明会で、他の5名の方と「東京日帰り出張」という、 ハードスケジュールにて、説明を聞いてきた。 説明は、以下の5テーマで行われた。
- 高等専門学校機関別認証評価について
- 評価基準の資料作成にあたっての留意事項
- 教育の質の保証にあたっての資料
- 自己評価の方法などについて
- 申請手続きの流れ
という感じで説明を受けた。特に前回受審との違いについての変わった点では、 現状実施のエビデンスでは不足していると思われる点がいくつか見受けられた。 特に、説明者が何度も繰り返し説明していた点は、 高専の目的として、『使命・基本方針・達成目標』について明記して、この点を満たしていることを示す客観的なエビデンスが必要という点であった。
どちらにしろ、エビデンス作りなどでは全学的な取り組みも必要だし、 他の先生への説明という点で、みんなそろって 「配布のパワポ資料レジメの電子データを配布して欲しい…」 との感想で終わりました。
ファーストクラス客も100円寿司に行ってこい
ANAの目玉サービス、クレーム殺到で中止との記事をみかけた。 飛行機のファーストクラス・ビジネスクラスの座席で、 食事や飲み物などのサービスをタッチパネルでオーダーできるシステムを導入したけど、 操作をすぐに理解した人はいいけど、操作に慣れない人はサービスの悪循環で、 オーダーが出てくるまで待たされすぎてクレーム多発の末、 お金をかけたサービスだけど中止となったらしい。
最初は、タッチパネルの『ユーザインタフェースプログラムが悪いんじゃ?』とも思ったが、 記事によると使いこなす人はさっさと注文している様子。 となると、タッチパネルオーダに慣れない人種の問題にも思えてくる。
ということで、私なりの結論: 金持ちだからって高いすし屋に行くばっかりじゃなくって、 100円の回るすし屋の、タッチパネルオーダに慣れてから飛行機に乗れってことですね。
継承と仮想関数
先週は、派生・継承について説明を行ったが、今日はその続き。
void main() { Person saitoh( "saitoh" , 45 ) ; Jyoshi ashida( "ashida" , 60 ) ; ashida.buka( &saitoh ) ; Person* list[2] ; list[0] = &saitoh ; list[1] = &ashida ; for( int i = 0 ; i < 2 ; i++ ) list[ i ]->print() ; }
この例では、list[1]=&ashida ができることが注目点。 派生クラスのポインタは、基底クラスのポインタに格下げが許される。 この例であれば、list[1]->print() では、list[1]=&ashida とする時点で、 Jyoshi型がPerson型になっているため、Person型のprint()が実行され、 部下の情報は表示されない。
しかし、実際のプログラムでは、list[1]->print() にて、Jyoshi::print() が呼び出して 欲しい場合も多い。こういった場合には、仮想関数を用いる。 virtual 宣言されたメソッドが宣言されると、データ構造の構築時に、 型情報を覚えるためのID(型情報)も保存される。 また、仮想関数の呼び出しでは、型情報に応じてメソッドが呼び出される。
class Person { : public: virtual void print() { printf( "%s %d\n" , name , age ) ; } } ; class Jyoshi : public Person { private: int size ; Person* table[ 5 ] ; public: virtual void print() { Person::print() ; for( int i = 0 ; i < size ; i++ ) table[i]->print() ; } } ;
パソコンでプログラムを打ち込みながら、受講している人がいたので、 Person型のサイズsizeof( Person )を確認すると、 virtual 宣言した場合、データサイズが4byte拡大することが確認できた。 実際には、型情報として「仮想関数の関数ポインタ配列へのポインタ」が 使われることが多いので、そのポインタ分の4byte増加と思われる。
int main(int argc,char**argv)
Cの授業でも、間違いとは説明するものの"void main(){}" でプログラムを書いていたり するけれど、C++だと明確にエラーになるため、argc,argvも含めて解説する。
int main( int argc , char*argv[] ) { for( int i = 0 ; i < argc ; i++ ) printf( "%s\n" , argv[i] ) ; // プログラムを a.out Hello World と実行すれば、 // argv[0]=a.out,argv[1]=Hello,argv[2]=World になる。 return 0 ; // mainの正常終了(プロセスのリターン値でOSに渡される) }
new delete
上記の仮想関数のプログラム例は、実プログラムでは、 以下のようなコードでインスタンスを生成する場合も多い。
Person *saitoh = new Person( "斉藤" , 45 ) ;
と簡単に説明しようとしたら、new,delete の説明をしてなかった。 new, delete は動的にメモリを確保するC言語のmalloc,freeに相当する演算子。
// C言語の場合 int *p ; if ( (p = (int*)malloc( sizeof(int) * 100 ) != NULL ) { // p[i] を整数配列として使える free( p ) ; } // C++のnew,deleteの場合 int *p = new int[ 100 ] ; // new演算子はメモリ確保の失敗には例外を使うので // NULLチェックは不要。 // p[i]を整数配列として使える delete [] p ; // Personの例で説明 Person* p = new Person( "斉藤" , 45 ) ; // new Personでは、コンストラクタも実行される。 p->print() ; delete p ; // delete では、デストラクタ呼び出しも行われる。
文字列の型と問題提起
過去の資料を使いながら、文字列の取り扱いで見落としがちな問題点を説明する。 特に、未初期化ポインタのトラブルと、バッファオーバフローについて説明を行う。
void foo( char s[] ) { : } void main() { char s[ 20 ] ; char *p ; scanf( "%s" , s ) ; foo( "1+2" ) ; // たぶん正しい。 foo( 1+2 ) ; // 文字と数式の区別がついていない foo( '1+2' ) ; // シングルクオートと、ダブルクオートの区別がついていない。 foo( s[ 100 ] ) ; // 配列サイズと添え字の区別がついていない人もいる。 foo( s ) ; // たぶん正しい。(バッファオーバフローの可能性あり) scanf( "%s" , p ) ; // 未初期化のポインタで入力 // (1) 多プロセスのメモリを触ってメモリエラー // (2) 自プロセスの多データを触って、変な動き。 }
バッファオーバフローとセキュリティ
バッファオーバフローとして、下記のようなプログラムの危険性を解説。 s[]が局所変数であれば、付近には関数からの戻り番地(PC)が保存されている。 あふれる領域で、PCを書き換え、PCの飛び先をあふれる領域の中のプログラムに してやると、想定外のプログラムを実行できる。
char s[ 10 ] ; // s[ | | | | | ] PC ウィルスプログラム scanf( "%s" , s ) ;
C言語では配列の範囲外アクセスチェックは行われない。
(1)はみ出さないようにチェックする。
(2)まちがったプログラムは修正する。
(3)既存のソフトでも間違いがあれば、アップデートを行うこと。 特にWindows Update。ただし、通常Microsoftは1ヶ月毎のアップデートなので、 1月以内に作られたウィルスには効き目が無いかも。
(4)ウィルス対策ソフトを入れること。 ただしウィルスが発見されてワクチンやウィルス情報が作られるまでには数日かかる。 数日以内に作られたウィルスには効き目が無いかも。
(5)こういったバッファオーバフローなどの危険性を理解して、 不用意にプログラムを実行することの危険性を理解すること。