0

関数内で pWinsock が削除されていないため、メモリ リークが発生しますか?

Winsock* CreateWinsock()
{
    Winsock* pWinsock=new Winsock;

    return pWinsock;
}

編集:実際には、上記のコードで新しく作成された Winsock を受け取ったのは Game (pWinsock) のメンバーであるため、ポインターを削除できません。これに問題はありますか?

class Game{
public:
    Game();
    ~Game();

    void CreateWindowClass(HINSTANCE);
    void CreateRessources(HINSTANCE);

    void ShowLoginScreen();

    HWND Getm_hWnd();

public:
    D2DResources* pD2DResources;
    Winsock* pWinsock;
    MessageLog* pMessageLog;

private:
    HWND m_hWnd;
};
4

3 に答える 3

2

関数内のメモリを削除すると、返されたポインタがダングリング ポインタになることに注意してください。これは、そのメモリがすでにクリアされているためです。このようなポインターの逆参照は未定義の動作です。

プログラムは、呼び出し元が自分でメモリを削除することを覚えていない場合にのみ、メモリ リークを引き起こします。関数内でメモリを割り当てて返したので、呼び出し後に何らかの形で削除する必要があります。メモリを削除するには、次のようになります。

Winsock *ptr = CreateWinsock(); // memory passed to ptr
// ...

delete ptr; // delete memory

問題は、呼び出し元に依存してメモリを削除することは、非常に面倒で信頼できないことです。この種の潜在的な問題は、やなどのスマート ポインターを使用することで軽減できます。これらのオブジェクトは、デストラクタが呼び出されるとメモリを削除するため、柔軟性が大幅に向上します。これがあなたのプログラムでどのように見えるかの例です:unique_ptrshared_ptr

std::unique_ptr<Winsock> CreateWinsock()
{
    return std::unique_ptr<Winsock>(new Winsock);
}

std::unique_ptr<Winsock> ptr = CreateWinsock();

カプセル化するスマート ポインターが責任を負うようになったため、ポインターを明示的に削除する必要はありません。

于 2013-03-17T18:42:22.590 に答える
0

この関数の呼び出し元が使用後にポインターを削除しても、リークは発生しません。したがって、このコードの断片だけが与えられたメモリ リークについてコメントするのは適切ではありません。

呼び出し元がオブジェクトの削除を忘れるなどの事態を回避するには、共有ポインタまたは別のスマート ポインタを使用します。

于 2013-03-17T18:43:20.630 に答える
0

いいえ、ポインタを Winsock に戻すだけです。例えば

Winsock* ws = CreateWinsock();
ws->doSomething();
//......
//some more stuff
//......
//Finished using Winsock
delete ws;

Winsock の使用が終了したときに delete が呼び出されなかった場合、Winsock が使用されなくなったときにメモリが占​​有されるため、メモリ リークと見なされます。

于 2013-03-17T18:44:26.823 に答える