new/deleteとNULL そして、deleteとdelete[]
Subクラス内のprivate変数uchar* list_がnewされているかどうかを判定する
そのとき、新たな変数を設けずに行う場合はNULLを使う
#include <iostream> class Base { public: Base() { std::cout << "Base : コンストラクタ" << std::endl; } virtual ~Base() { std::cout << "Base : デストラクタ" << std::endl; } }; class Sub : public Base { public: Sub() { std::cout << "Sub : コンストラクタ" << std::endl; list_ = NULL; std::cout << "NULL in list_" << std::endl; } virtual ~Sub() { std::cout << "Sub : デストラクタ" << std::endl; if(list_ != NULL) { delete[] list_; list_ = NULL; std::cout << "Delete list" << std::endl; } else { std::cout << "list_ is NULL" << std::endl; } } private: uchar* list_; }; int main(void) { Base* bmat = new Sub(); delete bmat; return 0; }
Base : コンストラクタ Sub : コンストラクタ NULL in list_ Sub : デストラクタ list_ is NULL Base : デストラクタ
C++ code by tanjoin - 44 lines - codepad
NULLで初期化しないと予想外のエラーが発生するので注意しないといけない
newをNULLで初期化する前もdeleteした後もNULLじゃなく別のところを指しているのも注意すべきかな
そのポインタが配列を指しているのかどうかなんてわからない
なんでdeleteとdelete[]の2つに分かれてるんだ
めんどくさい
#include <iostream> class Base { public: Base() { std::cout << "Base : コンストラクタ" << std::endl; } virtual ~Base() { std::cout << "Base : デストラクタ" << std::endl; } }; class Sub : public Base { public: Sub() { std::cout << "Sub : コンストラクタ" << std::endl; list_ = NULL; list_ = new uchar[5]; list_[0] = '0'; list_[1] = '1'; list_[2] = '2'; list_[3] = '3'; list_[4] = '4'; std::cout << "list_ is new uchar[5]" << std::endl; } virtual ~Sub() { std::cout << "Sub : デストラクタ" << std::endl; if(list_ != NULL) { delete[] list_; list_ = NULL; std::cout << "Delete list" << std::endl; } else { std::cout << "list_ is NULL" << std::endl; } } private: uchar* list_; }; int main(void) { Base* bmat = new Sub(); delete bmat; return 0; }
Base : コンストラクタ Sub : コンストラクタ list_ is new uchar[5] Sub : デストラクタ Delete list Base : デストラクタ
C++ code by tanjoin - 50 lines - codepad
delete list_;をdelete list_;にしてしまうとメモリリーク
先頭の要素しか解放されないからだそうで
かなり注意しないといけない
std::vectorとか使ったほうが楽だな
遅いけど
ここがわかりやすく説明してくれています