CInternetSessionでFTP接続するには?

解決


K  2010-01-19 11:46:06  No: 71278

現在、CInternetSessionを使用して、FTP接続を行おうとしているのですが、接続に失敗した際に、メモリリークが発生してしまい、困っています。
ソースは下記の通りです。開発環境はVS2008 MFCです。

【CHoge.h】
// メンバ変数
CInternetSession* m_pInternet;
CFtpConnection* m_pFtp;

【CHoge.cpp】
//コンストラクタでNULLに初期化
m_pInternet = NULL;
m_pFtp = NULL

// 接続処理
void CHoge::OnBnClickedBtnConnect()
{
    try
    {
        m_pInternet = new CInternetSession;
        m_pFtp = m_pInternet->GetFtpConnection
        (
            "Server", "User", "Pass",
            INTERNET_INVALID_PORT_NUMBER,
            TRUE
        );
    }
    catch (...)
    {
        if (m_pFtp)
        {
            m_pFtp->Close();
            delete m_pFtp;
            m_pFtp = NULL;
        }

        if (m_pInternet)
        {
            m_pInternet->Close();
            delete m_pInternet;
            m_pInternet = NULL;
        }
    }
}

現状は下記のような状態です。
①m_pInternet->GetFtpConnectionでFTP接続開始
②接続が存在しないため、例外が発生
③m_pFtpはNULLで初期化された状態なので、解放処理は無し。
④m_pInternetの解放処理を実行
⑤APL終了(×ボタンで手動で閉じる)
⑥memory leaks!(GetFtpConnection内で確保したメモリがリークしている?)

以上、宜しくお願い致します。


にーに  2010-01-19 20:20:16  No: 71279

自信ありませんけど
deleteするのに
m_pInternet = NULL;
してはまずいんじゃないでしょうか?


にーに  2010-01-19 20:52:29  No: 71280

ごめんなさい。勘違いでした。
なかったことにしてください


gak  2010-01-19 21:35:18  No: 71281

> ②接続が存在しないため、例外が発生
MFCは例外が発生した際、例外に関する情報を収めたクラスを new (と限っているワケではないが)してブン投げてくる。

> catch (...)
なので、このような形で例外を握り潰してしまうとMFC例外オブジェクトは投げられっ放しとなる。
で、その例外オブジェクトがヒープに確保されている類のモノだった場合リークしてしまう。

全ての例外を自分で拾いたい場合、↓のようにMFCの例外は別途処理してやる必要が有る。

try {
}
catch (CException* e) {
    e->Delete();
}
catch (...) {
}

コレが全原因かどうかは判らないが、とりあえず提示ソースを見て上記点が気になった。


K  2010-01-20 06:51:31  No: 71282

にーにさん、gakさん返信有難う御座います。

>MFCは例外が発生した際、例外に関する情報を収めたクラスを new (と限っているワケではないが)してブン投げてくる。
なるほど!そういうことだったのですね。
完全に想定外の箇所だったのでとても助かりました。
これからは例外を投げるクラスなどは注意して使用していきたいと思います。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加