スクリプト解析プログラムをデバッグモードで試験中にメモリリークを検出。
式アイテムのオブジェクトリスト解放時に delete してないのが原因でした。
割とよくあるバグ。
でも問題はそこではなくて、解析にまるまる一日かかってしまったこと(;^_^A
集中力が無くなってしまいました。途中睡魔に負けて昼寝してしまう始末(笑)
若いころはもっと集中力あったんですけどね、今は経験値でなんとかごまかしている感じです(´-ω-`)
メモリリークに悩まされる
Re: メモリリークに悩まされる
pExp なるポインタ型変数を使い回しているように見えるけど,特段使い回す理由が無いならば
スコープを各 new ~ delete の範囲に制限しても問題なさそうに見える.
で,そしたらスマートポインタがどうのでその辺の面倒なところを自動化できる可能性もありそうな?
スコープを各 new ~ delete の範囲に制限しても問題なさそうに見える.
で,そしたらスマートポインタがどうのでその辺の面倒なところを自動化できる可能性もありそうな?
Re: メモリリークに悩まされる
スマートポインタのことをよく知らないので、usao さんが書きました:2年前スマートポインタがどうのでその辺の面倒なところを自動化できる可能性もありそうな?
ポインタをコピーしたり上書きしてもほっとけば最後には自動的に実体を削除してくれるんですか。
だとしたら有効そうですね。
ポインタはクラスのメンバに保持していてデストラクタで削除するようにしてたんですが、
スクリプトにエラーがあって中断した場合、ワークのポインタをメンバにコピーせずに終了していた
にメモリリークが発生していました。
Re: メモリリークに悩まされる
ものすごくざっくりと言うと
newとdeleteを自前で書いてるとわりとミスる(deleteしないパスができるとか,逆に多重にdeleteするパスができる)ので,
「俺はある条件が満たされたらdeleteするぜ!」っていう仕組みを実装したもの(スマートポインタ)にその辺の管理は任せれば楽
…っていう話ですね.
まぁ,スマートポインタさえ使えばそれで何もかもが魔法のようにうまいこと解決してもらえるわけではなくて,例によって「こういう書き方をしてしまうと… → こうなってしまうぞ!(やめろ!)」っていうような注意事項は相応にあるのですが,
そういう「やめろ!」な事柄をしないように気を付けること VS 自前でミスらないコードを書くこと
で天秤にかけると,(そもそもこういうことを考えている場面というのは,後者側の難易度が問題となっている場面であるから)前者がいいかな,っていう感じ.
newとdeleteを自前で書いてるとわりとミスる(deleteしないパスができるとか,逆に多重にdeleteするパスができる)ので,
「俺はある条件が満たされたらdeleteするぜ!」っていう仕組みを実装したもの(スマートポインタ)にその辺の管理は任せれば楽
…っていう話ですね.
まぁ,スマートポインタさえ使えばそれで何もかもが魔法のようにうまいこと解決してもらえるわけではなくて,例によって「こういう書き方をしてしまうと… → こうなってしまうぞ!(やめろ!)」っていうような注意事項は相応にあるのですが,
そういう「やめろ!」な事柄をしないように気を付けること VS 自前でミスらないコードを書くこと
で天秤にかけると,(そもそもこういうことを考えている場面というのは,後者側の難易度が問題となっている場面であるから)前者がいいかな,っていう感じ.
Re: メモリリークに悩まされる
まともな情報源を見て,こういう実験をしてみて(なんなら「やめろ!」の実験とかもしてみて)雰囲気を掴んでみると良いかと.
class X //テスト用.deleteされた(→デストラクタが呼ばれた)を見る用
{
int m_v;
X( int v ) : m_v(v) {}
~X(){ std::cout<< "dtor " << m_v << std::endl; }
};
int main()
{
std::cout << "BeginTest(1)" << std::endl;
{//(1) shared_ptr のデストラクタが X を始末することを見るテスト
std::shared_ptr<X> sp1 = std::make_shared<X>( 1 );
}
std::cout << "EndTest(1)" << std::endl;
std::cout << "BeginTest(2)" << std::endl;
{//(2)途中で別のを管理することにされたら直前まで管理してた X の始末はどうなるのか?を見るテスト
auto sp10 = std::make_shared<X>( 10 );
auto sp20 = std::make_shared<X>( 20 );
std::cout << "Before sp10=sp20" << std::endl;
sp10 = sp20;
std::cout << "after sp10=sp20" << std::endl;
std::cout << "Before sp10.reset( new X(7) )" << std::endl;
sp10.reset( new X(7) );
std::cout << "After sp10.reset( new X(7) )" << std::endl;
std::cout << "Before sp20.reset( new X(90) )" << std::endl;
sp20.reset( new X(90) );
std::cout << "After sp20.reset( new X(90) )" << std::endl;
}
std::cout << "EndTest(2)" << std::endl;
return 0;
}
Re: メモリリークに悩まされる
>usaoさん
サンプルソースありがとうござます。
ポインタを値型の変数のように扱えるようになるんですね。これは使えますね。
vectorに入れたポインタも後始末を考えなくてもいいですし。
でも新しい技術を取り入れようとすると全体に対応したくなるし、
また新しいライブラリの地層が積み上がるなぁ・・・( 一一)
サンプルソースありがとうござます。
ポインタを値型の変数のように扱えるようになるんですね。これは使えますね。
vectorに入れたポインタも後始末を考えなくてもいいですし。
でも新しい技術を取り入れようとすると全体に対応したくなるし、
また新しいライブラリの地層が積み上がるなぁ・・・( 一一)