4

自分のメモリマネージャーのメモリ追跡と準備を試している間、新しい演算子をオーバーライドしようとしました。フリップコードに関する記事は、このプロセスの私の主要なガイドラインでした(http://www.flipcode.com/archives/How_To_Find_Memory_Leaks.shtml)。

その記事で説明されている手法を実装した後、STLのどこかに「crtdbg.h」が直接または間接的にインクルードされているヘッダーファイルの一部を介してインクルードされているという問題が残ります(Visual Studio 2010を使用) 。

これにより、エラーが発生します。

[...]10.0\vc\include\crtdbg.h(1078): error C2365: 'operator new' : redefinition; previous definition was 'function'
[...]10.0\vc\include\crtdbg.h(1078): error C2078: too many initializers
[...]

ヘッダーファイルをインクルードせずに「_CrtDumpMemoryLeaks()」を配置してクイックチェックを実行すると、ヘッダーファイルが実際にSTLファイルにインクルードされているという疑いが確認されます。

// The header files that should be included for using the CrtDumpMemoryLeaks:
//#define _CRTDBG_MAP_ALLOC
//#include <stdlib.h>
//#include <crtdbg.h>
//...
_CrtDumpMemoryLeaks()

独自の新規/削除を実装するのが良いかどうかは別として、いくつかの標準ライブラリ機能を使用し、これらの再定義エラーが発生しないようにしながら、独自の新規/削除実装を作成するにはどうすればよいか疑問に思います。


コードは次のようになります。

memdebug.h

#ifndef _MEM_DEBUG_H
#define _MEM_DEBUG_H

#ifdef _DEBUG
    void * operator new( unsigned int size, const char *filename, int line );
    void operator delete( void *ptr );

    #define DEBUG_NEW new(__FILE__, __LINE__)
    #define new DEBUG_NEW
#endif

#endif

memdebug.c

#ifdef _DEBUG
void * operator new( unsigned int size, const char *filename, int line )
{
    void *ptr = (void *)malloc(size);
    //AddTrack((DWORD)ptr, size, filename, line);
    return(ptr);
};

void operator delete( void *ptr )
{
    //RemoveTrack( (DWORD)ptr );
    free( ptr );
}
#endif

main.cpp

#include "memdebug.h"
#include <iostream>

void main()
{
    Test *pTest = new Test();
    std::cout << "end" << std::endl;
}

私がそれを解決した方法は、下を移動する#define new DEBUG_NEWこと<iostream>です; crtdbg.h;の新しいものを書き換えないため、問題は解決されました。ただし、これにより、ファイルを含む可能性のあるヘッダーの後にこれが常に実行されていることを確認する必要があり、非常に面倒になりcrtdbg.hます。

これは、新しい演算子にカスタム名を使用し、代わりにその名前を使用することによってのみ解決できると思います。私は正しいですか?

4

4 に答える 4

3

さて、今のところ、カスタムの「new」定義を使用せずに解決した方法は、すべてのファイルに含まれている「Engine.h」などの汎用ヘッダーファイルを作成したことです。これは、プロジェクト設定/構成プロパティ/ C / C ++ / Advancedの強制インクルードファイルを使用して適用できます。

このファイルには#defineが含まれています(memdebug.hから削除されました)

engine.h

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#include <windows.h>

#include "MemoryNappy.h"

#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW

これにより、システムはカスタムnew-defineの前にcrtdbg.hを考慮するようになり、そこで新しいものが変更されることはありません。2回目は、ラインのどこかに含まれていますが、以前にロードされたデータを使用しているだけです。(<iostream>インクルード後にインクルードする場合"engine.h")。

同じトリックを実行する可能性のあるサードパーティのライブラリを使用する場合、新しい演算子をオーバーライドすることは依然としてリスクの高いビジネスであることに注意してください。これにより、これらのファイルの新しい演算子が、ここで使用されているパターンを使用して書き直されます。その場合、次のフラグメントのように、カスタムの新しい定義の使用法を再検討することをお勧めします。

#define myNew new(__FILE__, __LINE__)

( http://www.flipcode.com/archives/Detecting_Memory_Leaks.shtmlにも記載されています)

于 2011-02-20T13:17:33.927 に答える
2

私たちのアプリケーションの1つでは、アプリケーションレベルnewでどこでも名前を変更しxnew、デバッグマクロをにのみ作用するものとして定義することにしましたxnew

マクロとして使用newおよび再定義すると、カスタムアロケータでも問題が発生する可能性があります。残念ながら、割り当て用のC ++構文により、デバッグラッパーの実行が困難になりました。

于 2011-02-19T22:23:33.547 に答える
0

Visual Studio 2010では、newまたはカスタム定義のnewを再定義することなくこれを行うことができました。次のヘッダーファイルを作成しました。

#pragma once
//_CRTDBG_MAP_ALLOC
//_CRTDBG_MAP_ALLOC_NEW
#define _CRTDBG_MAP_ALLOC
#define _CRTDBG_MAP_ALLOC_NEW
#include <stdlib.h>
#include <crtdbg.h>

プロジェクト設定/構成プロパティ/C/ C ++ /詳細で、すでに説明したオプション[ファイルの強制インクルード]を使用して、すべてのソースファイルにインクルードを強制しました。実際、crtdbg.hは、通常のnewの未定義とともに、newのこのカスタム定義をすでに実行しています。そして、すべてがスムーズに実行されることを確認するために、プロジェクト設定/構成プロパティ/ C / C++/プリプロセッサで利用可能なプリプロセッサ定義リストに_CRTDBG_MAP_ALLOCと_CRTDBG_MAP_ALLOC_NEWを追加しました。

これがこの問題に役立つことを願っています。

于 2013-03-27T18:42:12.273 に答える
-1

試してみてください_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);-私のブログ投稿で説明されているように、new再定義は必要ありません。

于 2011-11-09T05:05:24.850 に答える