SlideShare a Scribd company logo
1 of 114
Download to read offline
1
2014/07/12
イマドキC++erの
モテカワリソース管理術!
@hotwatermorning
C++an C++am(キ++ャンキ++ャン編集部)
2
C++?メモリリークするよね?
3
メモリリーク!
4
メモリの2重解放!
5
バグが取れない
6
納期に間に合わない
7
夏を満喫できない…><
8
モテカワになれない
夏を満喫できない…><
9
モテカワになれない
イマドキC++erの
モテカワリソース管理術を使うと…!?
メモリリークしない!!
10
二重解放も発生しない!!
11
プログラムの構造もすっきり!
12
納期に間に合う!!
13
夏を満喫できる!!
14
夏を満喫できる!!
15
モテカワになる
夏を
16
満喫するための
17
リソース管理術!
18
モテカワリソース管理術解説
19
モテカワリソース管理術解説
20
✤ メモリリークはなぜ発生するのか
✤ RAIIによるリソース管理
✤ RAIIでメモリリークを制する
✤ 他の言語のリソース管理と比較
モテカワリソース管理術解説
21
✤ メモリリークはなぜ発生するのか
✤ RAIIによるリソース管理
✤ RAIIでメモリリークを制する
✤ 他の言語のリソース管理と比較
メモリリークはなぜ発生するのか
22
メモリリークはなぜ発生するのか
23
✤ そもそもメモリリークとは?
✤ 動的に確保したメモリ領域の解放し忘れ
✤ メモリリソースの無駄になる
✤ リークが増えれば、メモリリソースが枯渇する
✤ 発生すると、原因の特定が難しいバグ
メモリリークはなぜ発生するのか
✤ C言語やC++は、GC(Garbage Collection)の
仕組みを持っていない
✤ GC : プログラムの実行中に動的に確保したメモリ領域の
うち、不要になった部分を自動で解放する仕組み
24
void	 foo()
{
	 	 	 	 //	 int型10個分の領域を確保
	 	 	 	 int*	 numbers	 =	 malloc(	 sizeof(	 int	 )	 *	 10	 );
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;	 	 
	 	 	 	 //	 使い終わったら解放
	 	 	 	 free(	 numbers	 );
}
mallocとfreeの対応
25
void	 foo()
{
	 	 	 	 //	 int型10個分の領域を確保
	 	 	 	 int*	 numbers	 =	 malloc(	 sizeof(	 int	 )	 *	 10	 );
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;	 	 
	 	 	 	 //	 使い終わったのに、解放してない。
	 	 	 	 free(	 numbers	 );
}	 	 	 //	 mallocで確保した領域はもうだれも知らない
	 	 	 	 //	 =>	 メモリリーク発生
メモリリーク
26
void	 foo()
{


 //	 int型10個分の領域を確保
	 	 	 	 int*	 numbers	 =	 malloc(	 sizeof(	 int	 )	 *	 10	 );
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;
	 	 	 	 
	 	 	 	 //	 使い終わったら解放	 	 
	 	 	 	 free(	 numbers	 );
	 	 	 	 
	 	 	 	 //	 すでに解放した領域にアクセスした
	 	 	 	 //	 =>	 Undefined	 behavior
	 	 	 	 numbers[0]	 =	 101;
}
ダングリングポインタ
27
void	 foo()
{


 //	 int型10個分の領域を確保
	 	 	 	 int*	 numbers	 =	 malloc(	 sizeof(	 int	 )	 *	 10	 );
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;
	 	 	 	 
	 	 	 	 //	 使い終わったら解放	 	 
	 	 	 	 free(	 numbers	 );
	 	 	 	 
	 	 	 	 //	 解放した領域を再度解放しようとした
	 	 	 	 //	 =>	 Undefined	 behavior
	 	 	 	 free(	 numbers	 );
}
2重開放
28
C言語のメモリ管理
29
✤ malloc()で動的に確保したメモリ領域は、
free()で確実に一度だけ解放する必要がある
✤ ポインタ変数は、そのメモリ領域を指すだけで、
その値の有効性や管理の仕方については知らない
✤ メモリ管理は完全にプログラマに任されている
void	 readFileAndOutput()
{
	 	 	 	 const	 char*	 file_name	 =	 "input.txt";
	 	 	 	 //	 ファイルからとあるデータの配列を読み込む
	 	 	 	 FileData*	 file_data	 =	 loadFileData(	 file_name	 );
	 	 	 
	 	 	 	 for(	 int	 i	 =	 0;	 i	 <	 file_data->length_;	 i++	 )
	 	 	 	 {
	 	 	 	 	 	 	 	 outputData(	 file_data->elements_[i]	 );
	 	 	 	 }
	 	 	 
	 	 	 	 //	 使い終わったら解放する
	 	 	 	 cleanupFileData(	 file_data	 );
}
メモリ管理の複雑な例
30
//	 データを保持する構造体
typedef	 struct	 FileData_tag
{
	 	 	 	 //	 データ数
	 	 	 	 int	 length_;
	 	 	 	 
	 	 	 	 //	 データ列
	 	 	 	 DataElement	 *elements_;
}
FileData;
メモリ管理の複雑な例
31
//	 ファイルからデータの配列を読み込んで返す
FileData*	 loadFileData(	 const	 char*	 file_name	 )
{
	 	 	 	 //	 FileData型のオブジェクトを確保する
	 	 	 	 FileData*	 file_data	 =	 
	 	 	 	 	 	 	 	 malloc(	 sizeof(	 FileData	 )	 );
	  memset(	 file_data,	 0,	 sizeof(	 FileData	 )	 );
	 	 	 	 
	 	 	 	 //	 ファイルの内容をfile_dataに読み込む
	 	 	 	 parseFile(	 file_name,	 file_data	 );
	 	 	 	 //	 読み込んだデータを返す
	 	 	 	 return	 file_data;
}
メモリ管理の複雑な例
32
//	 確保したFileData型のオブジェクトを解放する
void	 cleanupFileData(	 FileData*	 file_data	 )
{
	 	 	 	 free(	 file_data	 );
}
メモリ管理の複雑な例
33
このコードには怪しい臭いが漂っている。
loadFileData関数で確保した領域を
cleanupFileDataで正しく開放しているように
見えるが・・・
明らかにそれ以外に確保している領域があるはず。
//	 ファイルからデータの配列を読み込んで返す
FileData*	 loadFileData(	 const	 char*	 file_name	 )
{
	 	 	 	 //	 FileData型のオブジェクトを確保する
	 	 	 	 FileData*	 file_data	 =	 
	 	 	 	 	 	 	 	 malloc(	 sizeof(	 FileData	 )	 );
	  memset(	 file_data,	 0,	 sizeof(	 FileData	 )	 );
	 	 	 	 
	 	 	 	 //	 ファイルの内容をfile_dataに読み込む
	 	 	 	 parseFile(	 file_name,	 file_data	 );
	 	 	 	 //	 読み込んだデータを返す
	 	 	 	 return	 file_data;
}
メモリ管理の複雑な例
34
//	 ファイルをオープンして、各行のデータを読み込む
void	 parseFile(	 const	 char*	 file_name,
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 FileData*	 file_data)
{
	 	 	 	 FILE*	 file	 =	 fopen(	 file_name	 );
	 	 	 	 fscanf(	 file,	 "%d",	 &file_data->length_	 );
	 	 	 	 //	 行数分のメモリ領域を確保
	 	 	 	 file_data->elements_	 =	 malloc(	 
	 	 	 	 	 	 	 	 sizeof(	 DataElement	 )	 *	 file_data->length_	 );
	 	 	 	 //すべての行のデータを読み込み
	 	 	 	 parseElements(	 file,
	 	 	 	 	 	 	 	 file_data->length_,	 file_data->elements_	 );
	 	 	 	 fclose(	 file	 );
}
内部で確保した領域
35
//	 ファイルをオープンして、各行のデータを読み込む
void	 parseFile(	 char*	 file_name,	 FileData*	 file_data)
{
	 	 	 	 FILE*	 file	 =	 fopen(	 file_name	 );
	 	 	 	 fscanf(	 file,	 "%d",	 &file_data->length_	 );
	 	 	 	 //	 行数分のメモリ領域を確保
	 	 	 	 file_data->elements_	 =	 malloc(	 
	 	 	 	 	 	 	 	 sizeof(	 DataElement	 )	 *	 file_data->length_	 );
	 	 	 	 //すべての行のデータを読み込み
	 	 	 	 parseElements(	 file,
	 	 	 	 	 	 	 	 file_data->length_,	 file_data->elements_	 );
	 	 	 	 fclose(	 file	 );
}
内部で確保した領域
36
//	 確保したFileData型のオブジェクトを解放する
void	 cleanupFileData(	 FileData*	 file_data	 )
{
	 	 	 	 free(	 file_data	 );
}
メモリ管理の複雑な例
37
file_dataが内部で持ってる
DataElementの配列を解放していない。
-> メモリリーク発生
//	 確保したFileData型のオブジェクトを解放する
void	 cleanupFileData(	 FileData*	 file_data	 )
{
	 	 	 	 //	 データを保持する配列が確保されていたら
	 	 	 	 if(	 file_data->elements_	 )	 {
	 	 	 	 	 	 	 	 //解放する
	 	 	 	 	 	 	 	 free(	 file_data->elements_	 );
	 	 	 	 }
	 	 	 	 free(	 file_data	 );
}
修正版
38
メモリ管理の責任
39
✤ C言語では、プログラマが明示的にメモリの確保
と解放を対応させる責任を持つ
✤ これはGC付きの言語との大きく異なる点
✤ さもなければメモリリークが発生
✤ なんらかのクリーンアップ用の関数によって確保
/解放の対応付けを集約できたとしても、結局
loadFileData()とcleanupFileData()を対応させ
るような責任がプログラマにある
public	 static	 void	 foo()
{
	 	 	 	 //	 動的に確保したメモリ領域
	 	 	 	 int[]	 numbers	 =	 new	 int[10];
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;
	 	 	 	 //	 解放の処理は書かなくていい
	 	 	 	 //	 プログラム上でメモリ領域が不要になったら
	 	 	 	 //	 GCが適当なタイミングでその領域を解放する。
}
GC付き言語の例(Java)
40
GC付き言語のメモリ管理
41
✤ GC付き言語では、確保したメモリ対する解放処
理はGCによって自動的に行われるので、プログ
ラマは解放の責任を負わない
C++の場合
✤ C++にはGCが無いため、C言語と同様に、
動的に確保したメモリ領域は自動的に解放され
ない
42
void	 foo()
{
	 	 	 	 //	 int型10個分の領域を確保
	 	 	 	 int*	 numbers	 =	 new	 int[10];
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;
	 	 	 	 
	 	 	 	 //	 使い終わったらその領域を解放
	 	 	 	 delete	 []	 numbers;
}
C++の場合
43
void	 foo()
{
	 	 	 	 //	 int型10個分の領域を確保
	 	 	 	 int*	 numbers	 =	 new	 int[10];
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;
	 	 	 	 
	 	 	 	 //	 解放処理を忘れると	 =>	 メモリリーク
	 	 	 	 delete	 []	 numbers;
}
	 	 	 	 //	 ダングリングポインタや2重解放もC言語と同様
C++の場合
44
C++の場合
45
✤ ただしC++には、動的にメモリ領域を扱うための
クラスが用意されている
✤ std::vector, std::list, std::deque, etc, ...
void	 foo()
{
	 	 	 	 //	 int型10個分の領域を持つ
	 	 	 	 //	 vector<int>のオブジェクトを構築する
	 	 	 	 std::vector<int>	 numbers(	 10	 );
	 	 	 	 
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;
	 	 	 	 
}	 	 	 //	 vectorクラスで確保したメモリは自動で解放される
	 	 	 	 //	 ・・・どうやって?
vectorクラス
46
void	 foo()
{
	 	 	 	 //	 オブジェクト作成	 =>	 コンストラクタの呼び出し
	 	 	 	 std::vector<int>	 numbers(	 10	 );
	 	 	 	 
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;
	 	 	 	 
}	 	 	 //	 スコープから抜ける	 =>	 デストラクタの呼び出し
コンストラクタ/デストラクタ
47
//	 std::vectorクラスの定義のイメージ
template<class	 T>	 
class	 vector
{
private:
	 	 	 	 T	 *data_;
	 	 	 	 
public:
	 	 	 	 //	 コンストラクタ
	 	 	 	 vector(	 size_t	 capacity	 )
	 	 	 	 {
	 	 	 	 	 	 	 	 data_	 =	 new	 T[capacity];
	 	 	 	 }
クラスによるメモリ管理
48
//	 デストラクタ
	 	 	 	 ~vector()
	 	 	 	 {
	 	 	 	 	 	 	 	 delete	 []	 data_;
	 	 	 	 }
	 	 	 	 
	 	 	 	 //	 アクセッサ
	 	 	 	 T&	 operator[](	 size_t	 index	 )
	 	 	 	 {
	 	 	 	 	 	 	 	 return	 data_[index];
	 	 	 	 }
};
クラスによるメモリ管理
49
void	 foo()
{
	 	 	 	 //	 変数の定義とコンストラクタ呼び出し
	 	 	 	 std::vector<int>	 numbers;
	 	 	 	 numbers.vector(	 10	 );	 //	 指定サイズでメモリを確保
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;
	 	 	 	 //	 変数の破棄時にデストラクタの呼び出し	 	 	 	 
	 	 	 	 numbers.~vector();	 //	 確保したメモリ領域を解放
}
実行イメージ(擬似コード)
50
void	 foo()
{
	 	 	 	 //	 int型10個分の領域を持つ
	 	 	 	 //	 vector<int>のオブジェクトを構築する
	 	 	 	 std::vector<int>	 numbers(	 10	 );
	 	 	 	 
	 	 	 	 numbers[0]	 =	 100;
	 	 	 	 numbers[5]	 =	 200;
	 	 	 	 numbers[9]	 =	 1000;
	 	 	 	 
}
クラスによるメモリ管理
51
クラスがメモリを管理しているのでプログラマが
メモリ管理を意識する必要がない
C++でのメモリ管理
52
✤ C++ではクラスの仕組みの中に、メモリ管理を
隠 できる
モテカワリソース管理術解説
53
✤ メモリリークはなぜ発生するのか
✤ RAIIによるリソース管理
✤ RAIIでメモリリークを制する
✤ 他の言語のリソース管理と比較
メモリ以外のリソース
54
✤ クラスの仕組みで管理できるリソースはメモリ
だけではない
✤ ファイル
✤ Mutex
✤ その他、Socket, DBコネクション, etc, ...
void	 foo()
{
	 	 	 	 //	 ファイルをオープン
	 	 	 	 std::fstream	 file(	 "output.txt"	 );	 	 	 	 
	 	 	 	 //	 ファイルに書き込み
	 	 	 	 file	 <<	 "hello	 world."	 <<	 std::endl;	 
	 	 	 	 
}	 	 	 //	 スコープを抜けるとファイルを自動でcloseする
ファイルの例
55
ファイル(ファイルハンドル)というリソースを、
std::fstreamというクラスの中で管理している
std::mutex	 g_mutex;
void	 thread_proc(	 AwesomeSharedData*	 d	 )
{
  //	 ミューテックスのロックを取得
	 	 	 	 std::lock_guard<std::mutex>	 lock(	 g_mutex	 );
	 	 	 	 	 	 	 	 
	 	 	 	 ModifySharedData(	 d	 );
	 	 	 	 
}	 	 	 //	 ミューテックスのロックを解放
Mutexの例
56
ミューテックスのロック状態というリソースを、
std::lock_guardというクラスの中で管理している
std::mutex	 g_mutex;	 //	 lock()/unlock()という
          //	 メンバ関数を持つ
void	 thread_proc(	 AwesomeSharedData*	 d	 )
{
	 	 	 	 std::lock_guard<std::mutex>	 lock(	 g_mutex	 );
	 	 	 	 	 	 	 	 
	 	 	 	 ModifySharedData(	 d	 );
	 	 	 	 
}
Mutexの例
57
template<class	 MutexType>
class	 lock_guard
{
private:
	  MutexType	 *m_;
public:
	 	 	 	 //	 コンストラクタ
	  lock_guard(	 MutexType&	 m	 )
	 	 	 	 :	 m_(	 &m	 )
	  {	 m_->lock();	 }
	 	 	 	 
	 	 	 	 //	 デストラクタ
	 	 	 	 ~lock_guard()
	 	 	 	 {	 m_->unlock();	 }
};
クラス定義のイメージ
58
RAII
59
✤ このように、なんらかのリソースの確保/解放を
オブジェクトの寿命に紐付けて、リソースを管理
する手法(idiom)
✤ 「あーる・えー・あい・あい」
✤ Resource Acquisition Is Initialization
✤ 三つの利点(カプセル化、例外安全性、局所性)
RAII
60
✤ このように、なんらかのリソースの確保/解放を
オブジェクトの寿命に紐付けて、リソースを管理
する手法(idiom)
✤ 「あーる・えー・あい・あい」
✤ Resource Acquisition Is Initialization
✤ 三つの利点(カプセル化、例外安全性、局所性)
std::mutex	 g_mutex;
void	 thread_proc(	 AwesomeSharedData*	 d	 )
{
	 	 	 	 std::lock_guard<std::mutex>	 lock(	 g_mutex	 );
	 	 	 	 	 	 	 	 
	 	 	 	 ModifySharedData(	 d	 );
	 	 	 	 
}
Mutexの例
61
ロック状態というリソースを取得したい
=> そのためのオブジェクトを作って初期化する
RAII
62
✤ スマートポインタクラスのように、
とあるリソースの確保/解放をオブジェクトの
寿命に紐付けて、リソースを管理する方法
✤ Resource Acquisition Is Initialization
✤ 「あーる・えー・あい・あい」
✤ 三つの利点(カプセル化、例外安全性、局所性)
カプセル化
✤ さまざまなリソースを、オブジェクトの寿命とい
う形で、同じように管理できる
✤ リソース毎に異なる管理方法の詳細を知る必要が
ない
✤ ファイル : open / close
✤ ミューテックス : lock / unlock
✤ メモリ : new / delete
63
例外安全性
✤ 正常系の動作でも、例外発生時にも、同じように
リソースの解放処理が行われる
✤ 例外が発生したことによって、プログラムが不正
な状態になってしまうことがない
✤ 参考 : 「Exceptional C++―47のクイズ形式に
よるプログラム問題と解法 (C++ in-Depth
Series)」(必読)
64
std::mutex	 g_mutex;
void	 thread_proc(	 AwesomeSharedData*	 d	 )
{
	 	 	 	 //	 直接lock()/unlock()する
	  g_mutex.lock();
	 	 	 	 	 	 	 	 
	 	 	 	 ModifySharedData(	 d	 );
	 	 	 	 
	 	 	 	 g_mutex.unlock();
}
例外安全ではない例
65
std::mutex	 g_mutex;
void	 thread_proc(	 AwesomeSharedData*	 d	 )
{
	 	 	 	 //	 直接lock()/unlock()する
	  g_mutex.lock();
	 	 	 	 //	 この関数が例外を投げると
	 	 	 	 ModifySharedData(	 d	 );
	 	 	 	 //	 ミューテックスがロックされたままになる
	 	 	 	 g_mutex.unlock();
}
例外安全ではない例
66
std::mutex	 g_mutex;
void	 thread_proc(	 AwesomeSharedData*	 d	 )
{
	 	 	 	 std::lock_guard<std::mutex>	 lock(	 g_mutex	 );
	 	 	 	 //	 この関数が例外を投げても	 	 	 	 
	 	 	 	 ModifySharedData(	 d	 );
	 	 	 	 
}	 	 	 //	 その例外がさらに外に送出される際に変数`lock`の
	 	 	 	 //	 デストラクタが呼ばれる
例外安全になる
67
RAIIによって、
unlock()が呼ばれるのを保証できる
局所性
✤ RAIIはクラス定義にリソース確保と解放の処理を
記述する
✤ リソースを使用する側のコードがプログラム中に
散らばらない
✤ そのため、リソース管理のコードの局所性が高い
68
(余談)これからのRAII
✤ RAIIのクラスを簡単に定義するためのラッパーク
ラスが提案されている
✤ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3677.html
✤ まだ標準に取り込まれてないが、ライブラリ実装
なので、自分でも定義できる
✤ リソース管理がより簡単になる
69
モテカワリソース管理術解説
70
✤ メモリリークはなぜ発生するのか
✤ RAIIによるリソース管理
✤ RAIIでメモリリークを制する
✤ 他の言語のリソース管理と比較
スマートポインタ
71
✤ C++ではRAIIによって、クラスのオブジェクトで
メモリを管理できる
✤ さらに、C++には演算子オーバーロードによって
ポインタのように振舞うクラスが定義できる
✤ 演算子オーバーロード :
演算子の機能を再定義できる仕組み
void	 foo()
{
	 	 	 	 //	 生のポインタを受け取って中で管理するクラス
	 	 	 	 std::unique_ptr<AwesomeClass>	 p(
	 	 	 	 	 	 	 	 new	 AwesomeClass	 );
	 	 	 	 
	 	 	 	 //	 通常のポインタのように使用できる
	 	 	 	 p->MemberFunction();
	 	 	 	 p->member_variable_;
	 	 	 	 
	 	 	 	 
}
ポインタのように振舞う
72
void	 foo()
{
	 	 	 	 //	 生のポインタを受け取って中で管理するクラス
	 	 	 	 std::unique_ptr<AwesomeClass>	 p(
	 	 	 	 	 	 	 	 new	 AwesomeClass	 );
	 	 	 	 
	 	 	 	 //	 通常のポインタのように使用できる
	 	 	 	 p->MemberFunction();
	 	 	 	 p->member_variable_;
	 	 	 	 
	 	 	 	 //	 pが生きているときは
	 	 	 	 //	 内部で管理しているポインタが有効
	 	 	 	 
}	 	 	 //	 オブジェクトがデストラクトされるときに
	 	 	 	 //	 自動でdeleteを呼び出すのでリークしない
メモリを管理する
73
template<class	 T>
class	 unique_ptr
{
private:
	  T	 *p_;
	 	 	 	 
public:
	 	 	 	 //	 コンストラクタ
	  unique_ptr(	 T*	 p	 )
	 	 	 	 :	 p_(	 p	 )
	 	 	 	 {}
	 	 	 	 
	 	 	 	 unique_ptr	 (	 const	 unique_ptr&	 )	 =	 delete;
	 	 	 	 unique_ptr	 &	 
	 	 	 	 	  operator=(	 const	 unique_ptr&	 )	 =	 delete;
実装イメージ
74
//	 デストラクタ
	 	 	 	 ~unique_ptr()
	 	 	 	 {
	 	 	 	 	 	 	 	 delete	 p_;
	 	 	 	 }
	 	 	 	 
	 	 	 	 //	 アロー演算子(->)のオーバーロード
	 	 	 	 //	 unique_ptrクラスに対する->の操作を
	 	 	 	 //	 内部で管理してるポインタへの操作のように見せる
	 	 	 	 T	 *	 operator->()
	 	 	 	 {
	 	 	 	 	 	 	 	 return	 p_;
	 	 	 	 }
};
実装イメージ(続き)
75
スマートポインタを使うと
✤ deleteを意識する必要がない
✤ 例外発生時も安全
✤ メモリを返しても安全
76
void	 foo()
{
	 	 	 	 //	 生のポインタを受け取って中で管理するクラス
	 	 	 	 std::unique_ptr<AwesomeClass>	 p(
	 	 	 	 	 	 	 	 new	 AwesomeClass	 );
	 	 	 	 
	 	 	 	 //	 通常のポインタのように使用できる
	 	 	 	 p->MemberFunction();
	 	 	 	 p->member_variable_;
}
deleteを意識する必要がない
77
void	 foo()
{
	 	 	 	 A*	 p	 =	 new	 A;
	 	 	 	 
	 	 	 	 //	 この関数内で例外が発生すると
	 	 	 	 function_may_throw(	 p	 );
	 	 	 	 //	 ここまで実行パスが到達しないので
	 	 	 	 //	 メモリリーク発生
	 	 	 	 delete	 p;
}
例外発生時も安全
78
void	 foo()
{
	 	 	 	 std::unique_ptr<A>	 p(	 new	 A	 );
	 	 	 	 
	 	 	 	 //	 この関数内で例外が発生しても
	 	 	 	 function_may_throw(	 p	 );
	 	 	 	 //	 foo関数を抜ける際に変数`p`の
	 	 	 	 //	 デストラクタが安全にメモリを解放する
}
例外発生時も安全
79
void	 foo()
{
	 	 	 	 A*	 p	 =	 new	 A;
	 	 	 	 
	 	 	 	 try	 {
	  	 	 	 	 function_may_throw();
	 	 	 	 	 	 	 	 //	 正常系では正しく`p`を解放
	 	 	 	 	 	 	 	 delete	 p;
	 	 	 	 }	 catch(	 ...	 )	 {
	 	 	 	 	 	 	 	 //	 異常系でも`p`を解放する必要がある(冗長)
	 	 	 	 	 	 	 	 delete	 p;
	 	 	 	 	 	 	 	 throw;	 //再スロー(cf,	 例外中立)
	 	 	 	 }
}
try-catchでやろうとすると
80
void	 foo()
{
	 	 	 	 A*	 p	 =	 new	 A;
	 	 	 	 
	 	 	 	 try	 {
	  	 	 	 	 function_may_throw();
	 	 	 	 }	 finally	 {	 //	 擬似コード。C++にはfinallyはない
	 	 	 	 	 	 	 	 //	 正常系でも異常系でも同じく実行される
	 	 	 	 	 	 	 	 delete	 p;
	 	 	 	 }
}
finallyがあれば・・・?
81
void	 foo()
{
	 	 	 	 A*	 p	 =	 new	 A;
	 	 	 	 
	 	 	 	 try	 {
	  	 	 	 	 function_may_throw();
	 	 	 	 }	 finally	 {	 //	 擬似コード。C++にはfinallyはない
	 	 	 	 	 	 	 	 //	 正常系でも異常系でも同じく実行される
	 	 	 	 	 	 	 	 delete	 p;
	 	 	 	 }
}
finallyがあれば・・・?
82
C++にはRAIIや
後述のScopeExitがあるので
finallyは必須ではない
http://d.hatena.ne.jp/heisseswasser/20130508/1367988794
std::unique_ptr<B>	 bar()
{
	 	 	 	 std::unique_ptr<B>	 p(	 new	 B	 );
	 	 	 	 doSomethingWithB(	 p	 );


 return	 p;	 //	 関数から安全にポインタを返す
}
void	 baz()
{
	 	 	 	 std::vector<std::unique_ptr<B>>	 bs;
	  for(	 int	 i	 =	 0;	 i	 <	 10;	 ++i	 )	 {
    //	 安全な形で受け取って、取り扱う
	 	 	 	 	 	 	 	 bs.push_back(	 bar()	 );
	 	 	 	 }
}
ポインタを安全に返せる
83
make_uniqueを使おう
84
✤ make_uniqueとよばれるファクトリ関数を用意
すると、newも意識する必要がなくなる
✤ これは、C++11の標準には入っていない。
C+14から標準入りする予定。ただしC++11環境でも自作
するのは難しくない
✤ http://stackoverflow.com/questions/7038357/make-unique-and-perfect-forwarding
✤ http://herbsutter.com/gotw/_102/
//	 動的に作成したオブジェクトを直接
//	 unique_ptrの形で構築するラッパー関数があれば
template<class	 T>
std::unique_ptr<T>	 make_unique()
{
	  return	 std::unique_ptr<T>(	 new	 T	 );
}
//	 使う側でnewを意識する必要もなくなる
void	 foo()
{
	 	 	 	 std::unique_ptr<AwesomeClass>	 p	 =
	 	 	 	 	 	 	 	 make_unique<AwesomeClass>();
	 	 	 	 	 	 	 	 
}
make_uniqueを使おう
85
//	 動的に作成したオブジェクトを直接
//	 unique_ptrの形で構築するラッパー関数があれば
template<class	 T>
std::unique_ptr<T>	 make_unique()
{
	  return	 std::unique_ptr<T>(	 new	 T	 );
}
//	 使う側でnewを意識する必要もなくなる
void	 foo()
{
	 	 	 	 std::unique_ptr<AwesomeClass>	 p	 =
	 	 	 	 	 	 	 	 make_unique<AwesomeClass>();
	 	 	 	 	 	 	 	 
}
make_uniqueを使おう
86
プログラマがnewもdeleteも意識する必要が
なくなった
make_uniqueを使おう
87
✤ make_uniqueのような、スマートポインタの
ファクトリ関数を使用するのには正当な理由があ
る
✤ newを使っていると、微妙なケースでメモリリークの原因
となることがある
✤ autoキーワードと組み合わせれば、type量も減らせる
void	 foo(	 std::unique_ptr<A>	 pa,
	 	 	 	 	 	 	 	 	 	 std::unique_ptr<B>	 pb	 )
{
	 	 	 	 //...
}
void	 bar()
{
	 	 	 	 //	 foo関数呼び出し時の実引数の評価順は不定
	  foo(	 std::unique_ptr<A>(new	 A),
	 	 	 	 	 	 	 	 	 std::unique_ptr<B>(new	 B)	 )
}
newを使うと危険な場合
88
void	 foo(	 std::unique_ptr<A>	 pa,
	 	 	 	 	 	 	 	 	 	 std::unique_ptr<B>	 pb	 )
{
	 	 	 	 //...
}
void	 bar()
{


 //new	 Aが評価された直後、unique_ptr<A>の
	 	 	 	 //コンストラクタが評価されるより前に
	 	 	 	 //new	 Bが評価されるかもしれない
	  foo(	 std::unique_ptr<A>(new	 A),
	 	 	 	 	 	 	 	 	 std::unique_ptr<B>(new	 B)	 )
}
newを使うと危険な場合
89
void	 foo(	 std::unique_ptr<A>	 pa,
	 	 	 	 	 	 	 	 	 	 std::unique_ptr<B>	 pb	 )
{
	 	 	 	 //...
}
void	 bar()
{
	 	 	 	 //	 その場合、new	 Bが例外を投げたら?
	 	 	 	 //	 =>	 Aがリークする
	  foo(	 std::unique_ptr<A>(new	 A),
	 	 	 	 	 	 	 	 	 std::unique_ptr<B>(new	 B)	 )
}
newを使うと危険な場合
90
//	 動的に作成したオブジェクトを直接
//	 unique_ptrの形で構築するラッパー関数があれば
template<class	 T>
std::unique_ptr<T>	 make_unique()
{
	  return	 std::unique_ptr<T>(	 new	 T	 );
}
//	 make_uniqueの返り値の型はunique_ptrだと
//	 分かっているのでC++11の型推論キーワードが使える
void	 foo()
{
	 	 	 	 auto	 p	 =	 make_unique<AwesomeClass>();
	 	 	 	 	 	 	 	 
}
autoキーワードと組み合わせる
91
void	 readFileAndOutput()
{
	 	 	 	 const	 char*	 file_name	 =	 "input.txt";
	 	 	 	 //	 ファイルからとあるデータの配列を読み込む
	 	 	 	 std::unique_ptr<FileData>	 file_data	 =
	 	 	 	 	 	 	 	 loadFileData(	 file_name	 );
	 	 	 	 for(	 int	 i	 =	 0;	 i	 <	 file_data->elements_;	 i++	 )
	 	 	 	 {
	 	 	 	 	 	 	 	 outputData(	 file_data->[i]	 );
	 	 	 	 }
	 	 	 	 //	 使い終わったら・・・
	 	 	 	 //	 =>	 何もする必要がない!
}
最初の例がどうなるか
92
//	 データを保持する構造体
struct	 FileData
{
	 	 	 	 FileData()	 :	 num_data_(0)	 {}
	 	 	 	 //	 データ数
	 	 	 	 int	 num_data_;
	 	 	 	 //	 データ列
	 	 	 	 std::unique_ptr<DataElement[]>	 elements_;
};
最初の例がどうなるか
93
//	 ファイルからデータの配列を読み込んで返す
std::unique_ptr<FileData>	 
	 	 	 	 loadFileData(	 const	 char*	 file_name	 )
{
	 	 	 	 //	 FileData型のオブジェクトを確保する
	 	 	 	 auto	 file_data	 =	 std::make_unique<FileData>();
	 	 	 	 //	 ファイルの内容をfile_dataに読み込む
	 	 	 	 parseFile(	 file_name,	 file_data.get()	 );
	 	 	 	 //	 読み込んだデータを返す
	 	 	 	 return	 file_data;
}
最初の例がどうなるか
94
struct	 FCloser	 //	 デストラクト時に呼ばれる処理
{
	 	 	 	 void	 operator()(	 FILE*	 file	 )	 {	 fclose(file);	 }
};
//	 ファイルをオープンして、各行のデータを読み込む
void	 parseFile(const	 char*	 file_name,	 
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 FileData*file_data)
{
	 	 	 	 std::unique_ptr<FILE,	 FCloser>	 file(
	 	 	 	 	 	 	 	 	 	 	 	 fopen(	 file_name,	 "r"	 )	 );
	 	 	 	 fscanf(	 file.get(),	 "%d",	 &file_data->length_	 );
最初の例がどうなるか
95
//	 行数分のメモリ領域を確保
	 	 	 	 file_data->elements_	 =
	 	 	 	 	 	 	 	 std::make_unique<DataElement[]>(
	 	 	 	 	 	 	 	 file_data->length_	 );
	 	 	 	 //	 すべての行のデータを読み込み
	 	 	 	 parseElements(	 file.get(),
	 	 	 	 	 	 	 	 file_data->length_,
	 	 	 	 	 	 	 	 file_data->elements_.get()	 );
}
//	 クリーンアップ用の関数はいらなくなる
最初の例がどうなるか
96
RAIIでメモリリークを制する
97
✤ スマートポインタはメモリ管理にRAIIという手法
を使用したクラス
✤ スマートポインタを使用すると、メモリリークが
発生しないプログラムが書ける
✤ スライドでは紹介していないが、2重解放やダングリング
ポインタも発生しなくなる
モテカワリソース管理術解説
98
✤ メモリリークはなぜ発生するのか
✤ RAIIによるリソース管理
✤ RAIIでメモリリークを制する
✤ 他の言語のリソース管理と比較
他の言語のリソース管理
✤ 専用のスコープを用意する
✤ スコープを抜ける時に処理をする
99
他の言語のリソース管理
✤ 専用のスコープを用意する
✤ スコープを抜ける時に処理をする
100
専用のスコープを用意する
✤ C# : using構文
✤ Java : try-with-resource文
✤ Python : withステートメント
✤ Ruby : ブロック
101
public	 static	 void	 Function	 (	 string	 strFilename	 )
{
	 	 	 	 using	 (	 StreamWriter	 stream	 =
	 	 	 	 	 	 	 	 	 	 	 	 	 new	 StreamWriter	 (	 strFilename	 )	 )
	 	 	 	 {
	 	 	 	 	 	 	 	 stream.WriteLine("Loan	 Pattern!");
	 	 	 	 }
}
C#
102
File::open(	 "output.txt",	 "w"	 )	 {	 |f|
	 	 	 	 #	 オープンされたファイルオブジェクトを
	 	 	 	 #	 使ってごにょごにょ
	 	 	 	 f.puts	 "Block!"
}
#	 ブロックを抜けると自動でクローズされる
Ruby
103
Loan Pattern
104
✤ これらの言語のリソース管理の仕組みは、
ある関数や文のスコープ内でリソースを確保する
ようになっている
✤ C++のような、リソース管理がクラスのオブジェクトに
紐づく仕組みとは異なる点
✤ ScalaではLoan Patternと呼ばれる
✤ とあるスコープの中でだけリソースを拝借する
✤ Loan Patternも先に挙げたRAIIの3つの利点
(カプセル化、例外安全性、局所性)を持つ
RAII vs. Loan Pattern
✤ RAIIはリソースの管理に専用の構文が必要ない
✤ RAIIではリソースがオブジェクトに紐づいている
✤ リソースを持ち運べる
✤ スコープを超えてリソースを保持できる
✤ Loan Patternでは実現できないRAIIの利点
105
//	 なにか条件によって初期化状態が
//	 ことなるリソースを作る関数
MyResource
	  foo(	 Condition	 cond,	 Data	 data	 )
{
	  MyResource	 res(
	 	 	 	 	  getResourceHandle()	 );
	 	 	 	 if(	 cond	 )	 {
	 	 	 	 	 	 	 	 res.setStateWithData(data);
	  else	 {
	 	 	 	 	 	 	 	 res.setAnotherState();
	 	 	 	 }
	 	 	 	 return	 res;
}
リソースの受け渡し
106
C++でLoan Pattern
✤ Loan PatternはC++でも実装可能
✤ http://dev.activebasic.com/egtra/2014/03/24/654/
✤ http://carefulcode.blogspot.jp/2013/05/rifl-vs-raii.html
107
他の言語のリソース管理
✤ 専用のスコープを用意する
✤ スコープを抜ける時に処理をする
108
スコープを抜ける時に処理をする
109
✤ ScopeExitと呼ばれたりする
✤ D言語
✤ scope(exit), scope(failure)など
✤ RAIIも使える
✤ Go言語
✤ defer句(関数スコープのみ)
void	 abc()
{
	 	 	 	 Mutex	 m	 =	 new	 Mutex;
	 	 	 	 lock(m);

 //	 mutexをロック
	 	 	 	 //	 スコープ終了時にアンロック
	 	 	 	 scope(exit)	 unlock(m);
	 	 	 	 foo();

 //	 処理を行う
}
scope(exit) (D言語)
110
参考: http://www.kmonos.net/alang/d/exception-safe.html
RAIIのようなリソース管理用の専用の
クラスを作る必要がない => 簡単
void	 abc()
{
	 	 	 	 Mutex	 m	 =	 new	 Mutex;
	 	 	 	 lock(m);

 //	 mutexをロック
	 	 	 	 //	 スコープ終了時にアンロック
	 	 	 	 scope(exit)	 unlock(m);
	 	 	 	 foo();

 //	 処理を行う
}
scope(exit) (D言語)
111
参考: http://www.kmonos.net/alang/d/exception-safe.html
エラーが発生したときにだけ呼び出される
scope(failure)もあったり
C++でもScope Exit
112
✤ Boost.ScopeExitのように、C++でもScopeExit
を実現可能
✤ ただし言語機能ではなくライブラリ実装なので、D言語よ
りは冗長さがある
✤ https://sites.google.com/site/boostjp/tips/scope_guard
✤ www.boost.org/doc/libs/release/libs/scope_exit/
まとめ
113
✤ C++ではクラスの仕組みの中に、メモリ管理を
隠 できる
✤ クラスの仕組みの中でリソースを管理する手法を
RAIIと呼ぶ
✤ RAIIを使ったスマートポインタというクラスで
メモリリークを回避できる
参考文献やサイトなど
✤ Effective C++ 第3版
✤ Exceptional C++
✤ C++ ポケットリファレンス
✤ Working Draft, Standard for Programming Language C++ N3337
✤ http://herbsutter.com/gotw/_102/
✤ https://sites.google.com/site/boostjp/tips/scope_guard
✤ www.boost.org/doc/libs/release/libs/scope_exit/
✤ http://d.hatena.ne.jp/heisseswasser/20130508/1367988794
✤ http://dev.activebasic.com/egtra/2014/03/24/654/
✤ http://www.ne.jp/asahi/hishidama/home/tech/scala/sample/using.html
✤ http://carefulcode.blogspot.jp/2013/05/rifl-vs-raii.html
✤ http://www.kmonos.net/alang/d/exception-safe.html
114

More Related Content

What's hot

条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
MITSUNARI Shigeo
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
 
shared_ptrとゲームプログラミングでのメモリ管理
shared_ptrとゲームプログラミングでのメモリ管理shared_ptrとゲームプログラミングでのメモリ管理
shared_ptrとゲームプログラミングでのメモリ管理
DADA246
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
Kumazaki Hiroki
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
alwei
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
Satoshi Sato
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
Genya Murakami
 

What's hot (20)

Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
 
shared_ptrとゲームプログラミングでのメモリ管理
shared_ptrとゲームプログラミングでのメモリ管理shared_ptrとゲームプログラミングでのメモリ管理
shared_ptrとゲームプログラミングでのメモリ管理
 
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッド
 
競プロでGo!
競プロでGo!競プロでGo!
競プロでGo!
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
 
プログラムを高速化する話
プログラムを高速化する話プログラムを高速化する話
プログラムを高速化する話
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
 
LLVM最適化のこつ
LLVM最適化のこつLLVM最適化のこつ
LLVM最適化のこつ
 

Viewers also liked

Boost.GraphでJR全線乗り尽くしプランを立てる - プログラミング生放送+CLR/H+Sapporo.cpp 勉強会@札幌 (2014.7.12)
Boost.GraphでJR全線乗り尽くしプランを立てる - プログラミング生放送+CLR/H+Sapporo.cpp 勉強会@札幌 (2014.7.12)Boost.GraphでJR全線乗り尽くしプランを立てる - プログラミング生放送+CLR/H+Sapporo.cpp 勉強会@札幌 (2014.7.12)
Boost.GraphでJR全線乗り尽くしプランを立てる - プログラミング生放送+CLR/H+Sapporo.cpp 勉強会@札幌 (2014.7.12)
Hiro H.
 
Vi(m)を教えた話
Vi(m)を教えた話Vi(m)を教えた話
Vi(m)を教えた話
gu4
 
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
Hiro H.
 
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
Hiro H.
 
2012.11.17 CLR/H&札幌C++勉強会 発表資料「部分文字列の取得を 効率よく!楽に! - fundoshi.hppの紹介と今後の予定 -」
2012.11.17 CLR/H&札幌C++勉強会 発表資料「部分文字列の取得を効率よく!楽に! - fundoshi.hppの紹介と今後の予定 -」2012.11.17 CLR/H&札幌C++勉強会 発表資料「部分文字列の取得を効率よく!楽に! - fundoshi.hppの紹介と今後の予定 -」
2012.11.17 CLR/H&札幌C++勉強会 発表資料「部分文字列の取得を 効率よく!楽に! - fundoshi.hppの紹介と今後の予定 -」
Hiro H.
 
Roombaを鉄騎コントローラーで操縦してみた
Roombaを鉄騎コントローラーで操縦してみたRoombaを鉄騎コントローラーで操縦してみた
Roombaを鉄騎コントローラーで操縦してみた
Daisuke Nikura
 

Viewers also liked (20)

C++用将棋ライブラリ "OpenShogiLib"の紹介
C++用将棋ライブラリ"OpenShogiLib"の紹介C++用将棋ライブラリ"OpenShogiLib"の紹介
C++用将棋ライブラリ "OpenShogiLib"の紹介
 
Boost.GraphでJR全線乗り尽くしプランを立てる - プログラミング生放送+CLR/H+Sapporo.cpp 勉強会@札幌 (2014.7.12)
Boost.GraphでJR全線乗り尽くしプランを立てる - プログラミング生放送+CLR/H+Sapporo.cpp 勉強会@札幌 (2014.7.12)Boost.GraphでJR全線乗り尽くしプランを立てる - プログラミング生放送+CLR/H+Sapporo.cpp 勉強会@札幌 (2014.7.12)
Boost.GraphでJR全線乗り尽くしプランを立てる - プログラミング生放送+CLR/H+Sapporo.cpp 勉強会@札幌 (2014.7.12)
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
 
クロスプラットフォーム開発雑感 #pronamaclrhsapporocpp
クロスプラットフォーム開発雑感 #pronamaclrhsapporocppクロスプラットフォーム開発雑感 #pronamaclrhsapporocpp
クロスプラットフォーム開発雑感 #pronamaclrhsapporocpp
 
自宅サーバーを立てる話
自宅サーバーを立てる話自宅サーバーを立てる話
自宅サーバーを立てる話
 
Linux syllabus
Linux syllabusLinux syllabus
Linux syllabus
 
JA7YCQプログラミング勉強会 第1回 ~プログラミングやってみようか~
JA7YCQプログラミング勉強会 第1回 ~プログラミングやってみようか~JA7YCQプログラミング勉強会 第1回 ~プログラミングやってみようか~
JA7YCQプログラミング勉強会 第1回 ~プログラミングやってみようか~
 
Vi(m)を教えた話
Vi(m)を教えた話Vi(m)を教えた話
Vi(m)を教えた話
 
コンピュータに「最長しりとり」「最短距離でのJR線全線乗り尽くし」を解いてもらった方法
コンピュータに「最長しりとり」「最短距離でのJR線全線乗り尽くし」を解いてもらった方法コンピュータに「最長しりとり」「最短距離でのJR線全線乗り尽くし」を解いてもらった方法
コンピュータに「最長しりとり」「最短距離でのJR線全線乗り尽くし」を解いてもらった方法
 
C++ template-primer
C++ template-primerC++ template-primer
C++ template-primer
 
Sapporocpp#2 exception-primer
Sapporocpp#2 exception-primerSapporocpp#2 exception-primer
Sapporocpp#2 exception-primer
 
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
 
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
 
2012.11.17 CLR/H&札幌C++勉強会 発表資料「部分文字列の取得を 効率よく!楽に! - fundoshi.hppの紹介と今後の予定 -」
2012.11.17 CLR/H&札幌C++勉強会 発表資料「部分文字列の取得を効率よく!楽に! - fundoshi.hppの紹介と今後の予定 -」2012.11.17 CLR/H&札幌C++勉強会 発表資料「部分文字列の取得を効率よく!楽に! - fundoshi.hppの紹介と今後の予定 -」
2012.11.17 CLR/H&札幌C++勉強会 発表資料「部分文字列の取得を 効率よく!楽に! - fundoshi.hppの紹介と今後の予定 -」
 
最近のC++ @ Sapporo.cpp #5
最近のC++ @ Sapporo.cpp #5最近のC++ @ Sapporo.cpp #5
最近のC++ @ Sapporo.cpp #5
 
Introduction to boost test
Introduction to boost testIntroduction to boost test
Introduction to boost test
 
Heliumエンジンの設計と実装
Heliumエンジンの設計と実装Heliumエンジンの設計と実装
Heliumエンジンの設計と実装
 
Roombaを鉄騎コントローラーで操縦してみた
Roombaを鉄騎コントローラーで操縦してみたRoombaを鉄騎コントローラーで操縦してみた
Roombaを鉄騎コントローラーで操縦してみた
 
こんにちは、白い粉エバンジェリストの山口です
こんにちは、白い粉エバンジェリストの山口ですこんにちは、白い粉エバンジェリストの山口です
こんにちは、白い粉エバンジェリストの山口です
 
Programming camp code reading
Programming camp code readingProgramming camp code reading
Programming camp code reading
 

Similar to イマドキC++erのモテカワリソース管理術

C++ lecture-0
C++ lecture-0C++ lecture-0
C++ lecture-0
sunaemon
 
C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml
ssuser3a4b8c
 
Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版
Takuya Matsunaga
 
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
kenjis
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義
JPCERT Coordination Center
 
NVIDIA Japan Seminar 2012
NVIDIA Japan Seminar 2012NVIDIA Japan Seminar 2012
NVIDIA Japan Seminar 2012
Takuro Iizuka
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
digitalghost
 
CodeIgniter東京勉強会 2011.05.14
CodeIgniter東京勉強会 2011.05.14CodeIgniter東京勉強会 2011.05.14
CodeIgniter東京勉強会 2011.05.14
Takako Miyagawa
 

Similar to イマドキC++erのモテカワリソース管理術 (20)

2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ
 
Cpu cache arch
Cpu cache archCpu cache arch
Cpu cache arch
 
ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド
 ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド
ソフトウェアエンジニアのための「機械学習理論」入門・ハンズオン演習ガイド
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
initramfsについて
initramfsについてinitramfsについて
initramfsについて
 
Altera SDK for OpenCL解体新書 : ホストとデバイスの関係
Altera SDK for OpenCL解体新書 : ホストとデバイスの関係Altera SDK for OpenCL解体新書 : ホストとデバイスの関係
Altera SDK for OpenCL解体新書 : ホストとデバイスの関係
 
C++ lecture-0
C++ lecture-0C++ lecture-0
C++ lecture-0
 
20010901
2001090120010901
20010901
 
C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml
 
C++ Transactional Memory言語拡張の紹介
C++ Transactional Memory言語拡張の紹介C++ Transactional Memory言語拡張の紹介
C++ Transactional Memory言語拡張の紹介
 
Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版
 
10分でわかるFuelPHP @ 2011/12
10分でわかるFuelPHP @ 2011/1210分でわかるFuelPHP @ 2011/12
10分でわかるFuelPHP @ 2011/12
 
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1 10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
10分でわかるFuelPHP @ 2013/04 FuelPHP入門ハンズオン vol.1
 
C language Sem 01
C language Sem 01C language Sem 01
C language Sem 01
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義
 
NVIDIA Japan Seminar 2012
NVIDIA Japan Seminar 2012NVIDIA Japan Seminar 2012
NVIDIA Japan Seminar 2012
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
 
CodeIgniter東京勉強会 2011.05.14
CodeIgniter東京勉強会 2011.05.14CodeIgniter東京勉強会 2011.05.14
CodeIgniter東京勉強会 2011.05.14
 
10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
 10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya 10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya
 
RのffでGLMしてみたけど...
RのffでGLMしてみたけど...RのffでGLMしてみたけど...
RのffでGLMしてみたけど...
 

イマドキC++erのモテカワリソース管理術