5

小さなメモリリーク検出ツールを作成しようとしています。

私の考えは、アプリケーション内の動的メモリ割り当ての寿命を追跡して、使用中にアプリケーションがコアになる可能性のあるメモリへの無効なアクセスまたは削除されていないメモリを特定することです。

newとをオーバーライドするための単純なインターフェイスを作成したいと思いますdelete

そして、オーバーライドで、new関数行アドレスなどを出力したいと思いました。次に、標準を呼び出しますnew

誰かがすでにこれを試しましたか?クラス固有のnew演算子からstandardnewを呼び出すことができるかどうかわかりません。

4

4 に答える 4

0

::operator newクラス固有からの呼び出しoperator newは問題なく、非常に一般的です。の置換バージョンからグローバル演算子newを呼び出すことはできません::operator new。これは、グローバル演算子newを置換すると、古い演算子が存在しないためです。

于 2012-11-15T16:44:16.307 に答える
0

この質問では、私はあなたの問題に対するアドホックな解決策を提案しました:Windowsでのヒープ破損エラーの即時検出。どのように?

new一般に、とdeleteを次のコードに置き換えることができます。

DWORD PageSize = 0;

inline void SetPageSize()
{
    if ( !PageSize )
    {
        SYSTEM_INFO sysInfo;
        GetSystemInfo(&sysInfo);
        PageSize = sysInfo.dwPageSize;
    }
}

void* operator new (size_t nSize)
{
    SetPageSize();
    size_t Extra = nSize % PageSize;
    nSize = nSize + ( PageSize - Extra );
    return Ptr = VirtualAlloc( 0, nSize, MEM_COMMIT, PAGE_READWRITE);
}

void operator delete (void* pPtr)
{
    MEMORY_BASIC_INFORMATION mbi;
    VirtualQuery(pPtr, &mbi, sizeof(mbi));
    // leave pages in reserved state, but free the physical memory
    VirtualFree(pPtr, 0, MEM_DECOMMIT);
    DWORD OldProtect;
    // protect the address space, so noone can access those pages
    VirtualProtect(pPtr, mbi.RegionSize, PAGE_NOACCESS, &OldProtect);
}

メモリの無効なアクセスを判別します。さらなる議論では、リークの検出と他のメモリエラーの検出のアイデアが見つかります。

newglobalとを呼び出す場合は、グローバル名前空間プレフィックスdeleteを使用できます。::

return ::new(nSize);
于 2012-11-15T16:45:11.933 に答える
0

説明されているアプローチは合理的に聞こえます。これを拡張して、各割り当ての識別データの一部をデータ構造に格納できます。このようにして、すべての割り当て/割り当て解除ログを検査する必要なしに、プログラムの終了時に解放されていないすべてのメモリを追跡できます。

破損を検出するために、開始前と終了後に各割り当てをパディングでラップし、事前定義されたパターンで埋めることができます。メモリを解放すると、パターンがまだ適切に配置されていることを確認できます。これにより、破損を検出できる可能性が高くなります。

newスコーププレフィックスを使用してグローバルを呼び出すことができます: ::new

于 2012-11-15T16:49:59.533 に答える