2

私は現在、独自のメモリ リーク追跡システムに取り組んでいます。

私は Microsoft Visual C++ 2008 を使用しており、組み込みのものがあることは知っていますが、楽しみのために自分用に作成しています。

ただし、new コマンドと new[] コマンドをオーバーライドすると、何をしても関数の再定義エラーが発生します。

Microsoft Visual C++ の内部バインディングについてはよくわかりませんが、私とまったく同じマクロが CRT で既に定義されていると聞いたことがあります。

ここや他の場所で、これとまったく同じ質問に向けられた記事を見たことがありますが、人々は問題を解決したようには見えず、どのように解決したかについて明確な答えを出すこともできません.

これまでに私が持っているすべてのコードは次のとおりです。

MLD.h : http://pastebin.com/SfHzNaeN MLD.cpp : http://pastebin.com/aRhsTZpv

すべてのコードは、古いフリップコードの記事 (How To Detect Memory Leaks) に大まかに基づいています。申し訳ありませんが、2 つ以上のハイパーリンクを投稿する担当者が 10 人いないため、直接リンクを提供できません。

御時間ありがとうございます。

4

1 に答える 1

2

「関数の再定義エラー」は、おそらく MFC を使用しているためです。

ランタイム ライブラリは、そのような割り当ておよび割り当て解除関数を定義する業務に従事すべきではありません。

現在のコードの

struct MemLeakInfo
{
        unsigned int addr;
        unsigned int line;
        unsigned int size;
        unsigned char file;
};

悪いです。Anunsigned intは、32 ビット Windows であっても、アドレスを保持するのに十分な大きさであるとは限りません。代わりに、を使用してintptr_tください。

また、現在のコードの

void* operator new(unsigned int Size, int Line, const char* File);

悪いです。それは…

void* operator new( size_t Size, int Line, const char* File );

そして、あなたはoperator delete…のような対応する必要があります

void* operator delete( void* p, int Line, const char* File );

失敗したコンストラクター呼び出しからメモリの割り当てを解除するため。その非常に特定の状況でのみ呼び出されます。しかし、それがない場合は、MFC がかつてデバッグ ビルドで使用していたように、リークが発生しています。


EDIT:あなたが今提供したコードの修正バージョン:

ファイル [minimal.h]:

  • _MINIMAL_Hアンダースコアで始まり、その後に予約されている大文字が続くため、無効です。に変更MINIMAL_H
  • 使用size_tするには、 を含める必要があります<stddef.h>
  • _DEBUG標準マクロではありません。それはマイクロソフト主義です。assertこの目的のための標準マクロ ( のドキュメントを参照) は ですNDEBUG

 

#ifndef MINIMAL_H
#define MINIMAL_H

#include <stddef.h>     // std::size_t

#ifndef NDEBUG

void* operator new( size_t Size, int Line, const char* File );
void* operator new[]( size_t Size, int Line, const char* File );

void operator delete( void* ptr, int Line, const char* File );
void operator delete[]( void* ptr, int Line, const char* File ); 

#endif 

#ifndef NDEBUG

#define DEBUG_NEW new( __LINE__, __FILE__ )

#else

#define DEBUG_NEW new

#endif 

#endif //MINIMAL_H

ファイル [minimal.cpp]:

  • 使用mallocするには、 を含める必要がありますstdlib.h
  • 次のコードのキーワードで#define new大混乱を引き起こしている場合。new
  • C ではの結果を決してキャストしないでくださいmalloc。C++ では、必要な場合にのみ何かをキャストする必要があります。ここではそのような必要はありません。はマスク バグのみをキャストしますが、これはお勧めできません。
  • エラーの場合にリターンがありません。エラーの場合は、する必要がありますthrow std::bad_alloc。これは、これらの関数の神聖な標準の仕様によるものです。

 

#include "Minimal.h"

//#define new DEBUG_NEW

#ifndef NDEBUG
#include <stdlib.h>     // malloc
#include <exception>    // std::bad_alloc

void* operator new( size_t const size, int, const char*)
{
    void* const ptr = malloc( size );

    if( !ptr ) { throw std::bad_alloc(); }
    return ptr;
};

void* operator new[]( size_t const size, int, const char*)
{
    void* const ptr = malloc( size );

    if( !ptr ) { throw std::bad_alloc(); }
    return ptr;
}

void operator delete(void* const ptr, int, const char*)
{
    free( ptr ); 
};

void operator delete[]( void* const ptr, int, const char* )
{
    free( ptr ); 
}; 

#endif
于 2012-05-20T15:22:01.530 に答える