Microsoft PowerPoint - C++_第1回.pptx

Similar documents
Slide 1

02: 変数と標準入出力

02: 変数と標準入出力

Microsoft PowerPoint - prog03.ppt

02: 変数と標準入出力

memo

02: 変数と標準入出力

Microsoft PowerPoint - ep_cpp04.ppt

PowerPoint プレゼンテーション

Prog1_6th

PowerPoint プレゼンテーション

memo

第 3 回 Java 講座 今回の内容 今週の Java 講座はコレクション 拡張 for 文, ガベージコレクションについて扱う. 今週の Java 講座は一番内容が薄いも のになるだろう. コレクション コレクションとは大きさが決まっていない配列だと考えればよい. コレクションには List 先

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

デジタル表現論・第6回

プログラミング基礎

gengo1-11

memo

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

Prog1_10th

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

JavaプログラミングⅠ

Microsoft PowerPoint - adi05.ppt [互換モード]

PowerPoint プレゼンテーション

Microsoft PowerPoint ppt

Microsoft PowerPoint - lec10.ppt

Microsoft PowerPoint - 11.pptx

Microsoft PowerPoint - 12.ppt [互換モード]

Microsoft PowerPoint - 計算機言語 第7回.ppt

第1回 プログラミング演習3 センサーアプリケーション

program7app.ppt

基礎プログラミング2015

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

Microsoft PowerPoint - 13.ppt [互換モード]

スライド 1

2004/11/23 オブジェクト指向プログラミング - モデル図とシーケンス図の表現方法 - オブジェクト指向プログラミング (OOP:ObjectOrientedPrograming) オブジェクト指向プログラミング言語 (OOPL) Java,C++,Delphi(Pascal),Visual

デジタル表現論・第4回

02: 変数と標準入出力

プログラミングI第10回

Microsoft PowerPoint - 12.ppt [互換モード]

PowerPoint プレゼンテーション

02: 変数と標準入出力

Microsoft PowerPoint - 09.pptx

Javaプログラムの実行手順

02: 変数と標準入出力

PowerPoint プレゼンテーション

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

Microsoft PowerPoint - OS07.pptx

プログラミング基礎I(再)

02: 変数と標準入出力

ソフトゼミC 第二回 C++の基礎

02: 変数と標準入出力

Microsoft PowerPoint - kougi9.ppt

PowerPoint プレゼンテーション

Microsoft PowerPoint - lec06 [互換モード]

Javaの作成の前に

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

Microsoft PowerPoint - chap10_OOP.ppt

Prog1_15th

PowerPoint プレゼンテーション - 物理学情報処理演習

プログラミング入門1

講習No.9

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

情報処理Ⅰ演習

メディプロ1 Javaプログラミング補足資料.ppt

SuperH RISC engineファミリ用 C/C++コンパイラパッケージ V.7~V.9 ご使用上のお願い

02: 変数と標準入出力

プログラミング実習I

PowerPoint Presentation

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

(2) 構造体変数の宣言 文法は次のとおり. struct 構造体タグ名構造体変数名 ; (1) と (2) は同時に行える. struct 構造体タグ名 { データ型変数 1; データ型変数 2;... 構造体変数名 ; 例 : struct STUDENT{ stdata; int id; do

PowerPoint プレゼンテーション

Microsoft PowerPoint pptx

JavaプログラミングⅠ

Prog2_12th

Taro-ポインタ変数Ⅰ(公開版).j

Javaセキュアコーディングセミナー2013東京第1回 演習の解説

ガイダンス

Microsoft Word - matlab-coder-code-generation-quick-start-guide-japanese-r2016a

3.1 stdio.h iostream List.2 using namespace std C printf ( ) %d %f %s %d C++ cout cout List.2 Hello World! cout << float a = 1.2f; int b = 3; cout <<

Microsoft PowerPoint - prog07.ppt

Microsoft PowerPoint - kougi7.ppt

プログラミング入門1

Microsoft PowerPoint - prog04.ppt

た場合クラスを用いて 以下のように書くことが出来る ( 教科書 p.270) プログラム例 2( ソースファイル名 :Chap08/AccountTester.java) // 銀行口座クラスとそれをテストするクラス第 1 版 // 銀行口座クラス class Account String name

AquesTalk Win Manual

10-vm1.ppt

プログラミング及び演習 第1回 講義概容・実行制御

AquesTalk プログラミングガイド

Taro-リストⅠ(公開版).jtd

Microsoft Word - C言語研修 C++編 3.doc

第2回

Embarcadero Developer Camp

Prog2_9th

C 言語経験者のための C++ 入門

Microsoft PowerPoint - CproNt02.ppt [互換モード]

02: 変数と標準入出力

概要 プログラミング論 変数のスコープ, 記憶クラス. メモリ動的確保. 変数のスコープ 重要. おそらく簡単. 記憶クラス 自動変数 (auto) と静的変数 (static). スコープほどではないが重要.

Microsoft PowerPoint - prog06.ppt

Transcription:

OpenFoam のための C/C++ 第 1 回メモリ管理 田中昭雄 1

目的 この勉強会の資料があれば OpenFoam カスタマイズ時に C/C++ で迷わない 2

予定 第 1 回メモリ管理 第 2 回 OpenFOAM で勉強するクラス 第 3 回 OpenFOAM で勉強するテンプレート 第 4 回 OpenFOAM カスタマイズ 第 5 回未定 第 6 回未定 3

今回のテーマ C++ におけるメモリ管理について理解する メモリ管理にまつわるバグを直すは大変 バグを出さない事が肝要 バグを出さないために正しい理解 4

今回の前提 C 言語で 配列を使ったことがある 構造体を使ったことがある 関数を使ったことがある クラスという言葉を聞いたことがある C++ ベースで解説していきます 5

Agenda メモリリーク, 32bit / 64bit new/malloc, delete/free の違い メモリ確保 / 解放 C++ におけるスマートポインタ 6

Agenda メモリリーク, 32bit / 64bit new/malloc, delete/free の違い メモリ確保 / 解放 C++ におけるスマートポインタ 本章を読まなくてもプログラム書けますます 7

メモリリーク : バグの 1つ 32bit / 64bit: アプリケーション作成の設定利用可能なメモリ量が変わります 8

メモリ管理 malloc / freeとnew / delete malloc / freeの利用例 : int* p = (int*)malloc(sizeof(int)); *p = 100; std::cout << "content of p is " << *p << " n"; free(p); Content of p is 100 new / free の利用例 : int* p = new int(500); std::cout << "content of p is " << *p << " n"; delete p; Content of p is 500 大量データを利用したい場合にメモリ管理 9

メモリ領域の違い スタック 関数内の作業用一時変数 ( ローカル変数用 ) 高速 容量少ない ( 数 MB 程度 ) 確保 / 解放は自動 ヒープ 大規模データ取り扱い用 大容量 確保 / 解放はプログラマ責任 10

メモリ領域の違いローカル変数とnew/mallocで確保した変数の違い 例 : int num_array = 1000; for(int i = 0; i < num_array; ++i) int* p = new int(i); std::cout << i<< "th content is " << *p << " n"; delete p; } スタック領域 num_array : int p : int* ヒープ領域 Int 一つ分のメモリ領域 p はアドレスを格納したポインタ変数 11

メモリリークメモリを使っていないつもりだけど使っている状態 メモリリークの例 : intnum num_array = 1000; for(int i = 0; i < num_array; ++i) int* p = new int(i); std::cout << i<< "th content is " << *p << " n"; } 0 th content is0 1 th content is 1 999 th content is 999 解説 : for ループ内の p はローカル変数ループ毎に p の値 ( アドレス ) が更新 free されるべきアドレスはループ毎に分からなくなってしまう もう再利用も解放できない int1000 個分のメモリが無駄に利用されている 12

メモリリークメモリを使っていないつもりだけど使っている状態 原因は解放忘れ アプリケーション ( プロセス ) が利用可能な最大メモリ量は決まっている 最大メモリ量を超えるとクラッシュ ( 計算途中でも関係ない ) 13

ポインタ変数を覗いてみるポインタ変数の値 サイズはどうなっているのか int* pint = new int(100); double* pdouble = new double(200.5); std::cout << "pint is " << pint << " n"; std::cout << "size of pint is " << sizeof(pint) << " n"; std::cout t << "content tof pint ti is " << *pint << " n";" std::cout << "size of content of pint is " << sizeof(*pint) << " n"; std::cout << "pdouble is " << pdouble << " n"; std::cout << "size of pdouble is " << sizeof(pdouble) << " n"; std::cout << "content of pdouble is " << *pdouble << " n"; std::cout << "size of content of pdouble is " << sizeof(*pdouble) << " n"; delete pint; delete pdouble; 14

ポインタ変数を覗いてみるポインタ変数の値 サイズはどうなっているのか pint is 006E1DA8 size of pint is 4 content of pint is 100 size of content of pint is 4 pdouble is 005D8F60 size of pdouble is 4 content of pdouble is 200.5 size of content of pdouble is 8 ポインタ変数の値は変な値 ( アドレスを表現 ) ポインタ変数のサイズはint 用 double 用でも4byte(32bit) ポインタ変数の中身のサイズは int / doubleで異なる 15

ポインタ変数を覗いてみる ポインタ変数の中身は? アドレス ( 変数が格納されている郵便番号のようなもの ) ポインタ変数のサイズは? ビルド設定によって異なります (32bit or 64bit) 16

32bit / 64bit アプリアドレスの長さ ( ポインタ変数のサイズ ) の違い 64bit は 32bit よりアドレスが長い 32bit アプリの場合 ポインタ変数長は 32bit 64bit アプリの場合 ポインタ変数長は64bit ポインタ変数のサイズの違いが 利用可能なメモリ量の違いを生む 郵便番号の長さと同じ仕組み 17

他のプログラミング言語メモリの自動解放してくれる言語がある.NET (C# など ) Java Ruby 実行環境が確保したメモリを監視使われなくなったらメモリを自動解放してくれる ( ガーベッジコレクション ) 18

Agenda メモリリーク, 32bit / 64bit new/malloc, delete/free の違い メモリ確保 / 解放 C++ におけるスマートポインタ 19

C と C++ の違い C++ はCより色々なことができる C 仕様はC++ 仕様のサブセット ファイル拡張子.c /.cpp 今回はコンストラクタとデストラクタのみ説明 C++ C 20

クラス / 構造体理解しやすいように変数などをまとめる 3 次元ベクトル構造体例 : structvector3d double x, y, z; Vector3D() std::cout << Making Vector3D n ; x = 10, y = 10, z = 10; }; ~Vector3D() std::cout << Deleting Vector3D n"; }; }; 3 次元ベクトルクラス例 : class Vector3D public: double x, y, z; Vector3D() std::cout << Making Vector3D n ; x = 10, y = 10, z = 10; }; ~Vector3D() std::cout << Deleting Vector3D n"; }; }; public( アクセス修飾子のひとつ ) については次回説明予定 21

コンストラクタ / デストラクタクラス / 構造体の初期化 終了処理のための関数 3 次元ベクトルクラス例 : class Vector3D public: double x, y, z; Vector3D() std::cout << Making Vector3D n ; x = 10, y = 10, z = 10; }; ~Vector3D() std::cout << Deleting Vector3D n"; }; }; コンストラクタ : クラス名と同じメンバ関数メモリ確保時に自動実行この例では メモリ確保時に x, y, zを10に設定 デストラクタ : C++ の新機能 (C では利用不可 ) クラス名の前に ~ がついたメンバ関数メモリ解放時に自動実行この例では メモリ解放時に deleting Vector3D を表示 22

コンストラクタ / デストラクタクラス / 構造体の初期化 終了処理のための関数 3 次元ベクトルクラス例 : Vector3D vec; std::cout << "(x, y, z) = << vec.x << ", " << vec.y << ", " << vec.z << " n"; Making Vector3D (x, y, z) = 10, 10, 10 Deleting Vector3D 解説 : vec が Vector3D クラスのローカル変数としてメモリ確保 ( コンストラクタ実行 ) vec の x, y, z を表示 ( コンストラクタで 10 が設定 ) プログラム終了時にローカル変数 vec のメモリ解放 ( デストラクタ実行 ) 23

new/malloc, delete/free の違い 初期化 終了処理を呼び出す / 呼び出さない new と delete: Vector3D* vec = new Vector3D(); std::cout << "(x, y, z) = " << vec >x <<, << vec >y <<, << vec >z << " n"; delete vec; Mki Making Vector3D (x, y, z) = 10, 10, 10 Deleting Vector3D malloc と free Vector3D* vec = (Vector3D*)malloc(sizeof(Vector3D)); std::cout << "(x, y, z) = " << vec >x << ", " << vec >y << ", " << vec >z << " n"; free(vec); (x, y, z) = 6.27744e+066, 6.27744e+066, 6.27744e+066 x, y, z は初期化されていないため実際の表示は環境によって異なります 24

Agenda メモリリーク, 32bit / 64bit new/malloc, delete/free の違い メモリ確保 / 解放 C++ におけるスマートポインタ 25

1 つの変数のメモリ確保 / 解放 new と delete: Vector3D* vec = new Vector3D(); std::cout << "(x, y, z) = " << vec >x <<, << vec >y <<, << vec >z << " n"; delete vec; Making Vector3D (x, y, z) = 10, 10, 10 Deleting Vector3D malloc と free Vector3D* vec = (Vector3D*)malloc(sizeof(Vector3D)); vec >x = 10; vec >y = 10; vec >z = 10; std::cout << "(x, y, z) = " << vec >x << ", " << vec >y << ", " << vec >z << " n"; free(vec); (x, y, z) = 10, 10, 10 malloc を利用する場合は 個別に初期化必要 コンストラクタ実行されないため 26

配列のメモリ確保 / 解放変数 1つの場合と異なる命令が必要 new と delete: Vector3D* vec = new Vector3D[10]; std::cout << "(x, y, z) = " << vec[7].x <<, << vec[7].y <<, << vec[7].z << " n"; delete [] vec; 10 個分のコンストラクタ / デストラクタが実行されます malloc と free Vector3D* vec = (Vector3D*)malloc(sizeof(Vector3D) * 10); vec[0].x = 10; vec[0].y = 10; vec[0].z = 10; std::cout << "(x, y, z) = " << vec[7].x << ", " << vec[7].y << ", " << vec[7].z << " n"; free(vec); Making Vector3D (x, y, z) = 10, 10, 10 Deleting Vector3D (x, y, z) = 6.27744e+066, 6.27744e+066, 6.27744e+066 最初の配列要素の x, y, z は初期化しているが インデックスが 7 の配列要素は初期化されていないのでおかしな値が表示されます 27

配列のメモリ確保 / 解放連続したアドレスとしてメモリ確保 Vector3D* vec = new Vector3D[10]; 0 1 2 7 9 10 個分のVector3Dのメモリがnewによって確保配列要素毎にコンストラクタが実行 8 番目の配列要素を使いたい場合はvec[7] 最終要素のインデックスは9 for(int i = 0; i< 10; ++i) std::cout << vec[i].x <<, << vec[i].y <<, << vec[i].z << n ; } (ex) vec[7].x = 100 delete [] vec; vec として確保された配列 (10 個分の Vector3D) を delete によって解放配列要素毎にデストラクタが実行 28

配列のメモリ確保 / 解放ありがちな間違い delete vec; 配列のメモリが正しく解放されません場合によってはクラッシュ 場合によってはメモリ状態がおかしいまま計算続行 ( 計算処理には誤りがないのに結果がおかしい 状態 ) Vector3D* vec = new Vector3D[10]; vec[10].x = 100; 何に利用されているか分からないメモリの状態を変更しています場合によってはクラッシュ 場合によってはメモリ状態がおかしいまま計算続行 ( 計算処理には誤りがないのに結果がおかしい 状態 ) 脆弱性に分類 29

関数にデータを渡したい関数の引数に対する正しい理解が必要 典型的な誤り例 : void assign100intox(vector3d vecinfunc) vecinfunc.x = 100; }; int main() Vector3D vec; assign100intox (vec); std::cout << vec.x << ", " << vec.y << ", " << vec.z << " n"; return 0; } Making Vector3D Deleting Vector3D (x, y, z) = 10, 10, 10 Deleting Vector3D! この結果を理解できない ということは関数の引数を正しく理解していません 関数の引数は 関数内のローカル変数かつその値は呼び出し元のコピー 30

関数にデータを渡したい関数の引数に対する正しい理解が必要 void assign100intox(vector3d vecinfunc) スタック領域 vecinfunc.x = 100; }; vec : Vector3D int main() Vector3D vec; assign100intox (vec); std::cout << vec.x << ", " << vec.y << ", " << vec.z << " n"; return 0; } 解説 1vecがローカル変数として確保 vecinfunc : Vector3D ローカル変数として vec と vecinfunc は独立して存在 2vecInFuncがローカル変数として確保 3vecをvecInFuncへコピー 4vecInFuncのxを変更 5assign100IntoX 内のローカル変数であるvecInFuncを削除 ( 関数実行終了に伴い ) 31

関数にデータを渡したいアドレスを利用して解決 スタック領域 vecptr : Vector3D* vec : Vector3D vecptrinfunc : Vector3D* vecptr vecptrinfuncの値 ( アドレス ) で指定されているメモリ領域にある変数 ( スタックでもヒープでもOK) ローカル変数として vecptr と vecptrinfunc は独立して存在 関数引数としてアドレスを渡すアドレスであれば コピーであっても問題なし 32

関数にデータを渡したいポインタ変数 or 参照を利用 関数の引数にポインタ変数を利用した例 : void assign100intoxwithpointer(vector3d* vecptrinfunc) vecptrinfunc >x = 100; }; Making Vector3D (x, y, z) = 100, 10, 10 Deleting Vector3D int main() Vector3D vec; assign100intoxwithpointer (&vec); std::cout << vec.x << ", " << vec.y << ", " << vec.z << " n"; return 0; } ローカル変数などのアドレス (= ポインタ変数の値 ) は変数名の最初に & をつけるとアドレス取得 ポインタ変数がコピー = アドレスがコピーされて関数に渡される 33

関数にデータを渡したいポインタ変数 or 参照を利用 関数の引数に参照を利用した例 : void assign100intoxwithreference(vector3d& vecrefinfunc) vecrefinfunc.x = 100; }; Making Vector3D (x, y, z) = 100, 10, 10 Deleting Vector3D int main() Vector3D vec; assign100intoxwithreference (vec); std::cout << vec.x << ", " << vec.y << ", " << vec.z << " n"; return 0; } アドレス取得の & と同じ書き方と同じなので混同に注意 効果はポインタ変数と同じただし書き方が異なる 34

Agenda メモリリーク, 32bit / 64bit new/malloc, delete/free の違い メモリ確保 / 解放 C++ におけるスマートポインタ 35

メモリ管理は C/C++ の大きなテーマの一つ うっかりミスで重いバグ修正 プログラマは千差万別 スマートポインタとは いい感じに自動 deleteしてくれるクラス ( 属人的である技量に期待する部分を減らす努力す努 ) 36

基本的な考え方 コンストラクタで確保 / デストラクタで解放 3 次元ベクトルクラス例 : class Vector3DPtr public: Vector3D* Ptr; }; Vector3DPtr() Ptr = new Vector3D(); }; ~Vector3DPtr() delete Ptr; }; int main() Vector3DPtr vecptr; vecptr.ptr >x = 100; std::cout << vecptr.ptr >x << n ; return 0; } 実際に実行するためには #include <iostream> の記述が必要です デストラクタで メンバ変数で指定されたメモリ領域が解放 37

std::auto_ptr 標準ライブラリから利用できるスマートポインタ 3 次元ベクトルクラス例 : #include <memory> int main() std::auto_ptr<vector3d> aptrvec(new Vector3D()); aptrvec >x = 100; std::cout << aptrvec >x << ", " << aptrvec >y << ", " << aptrvec >z << " n"; return 0; } Making Vector3D (x, y, z) = 100, 10, 10 Deleting Vector3D 38

その他 Boost ライブラリ scoped_ptr ptr / scoped_array shared_ptr / shared_array 39

課題 STL ファイルを読み込んで 全ての頂点座標を csvファイルとして出力 必要な事 ファイル入出力 (fopen/fclose, ifstream/ofstream ft 文字列の一致判断 (strcmp, std::string::compare) 読み込んだ文字列を数値に変換 (atof) 文字列の分割 (strtok, std::string::substr) STLファイルフォーマット (hiramine.com STL フォーマットで検索 ) http://www.hiramine.com/programming/3dmodelfileformat/stlfilefor mat.html 40

C++ 学習 参考資料 独習 C++ http://www.amazon.co.jp/gp/product/47981 03187/ 仮想メモリ 仮想アドレス仮想アドレス http://software.fujitsu.com/jp/manual/ma nualfiles/m080099/j2uz9570/03z2a/t un07/tun00083.htm 41