web-dev-qa-db-ja.com

新規/削除のオーバーロード

プログラムでFinderを少しメモリリークさせていますが、newとdelete(およびnew []とdelete [])をオーバーロードする私の方法は何もしないようです。

void* operator new (unsigned int size, const char* filename, int line)
{
    void* ptr = new void[size];
    memleakfinder.AddTrack(ptr,size,filename,line);
    return ptr;
}

newをオーバーロードした方法は、上記のコードスニペットに示されています。 void *を返す演算子によるものだと思いますが、どうすればいいのかわかりません。

24
Brammie
void* ptr = new void[size];

できません。修理する。

グローバルに新規/削除をオーバーロードしようとしないでください。それらを基本クラスに入れて、このクラスからすべてのオブジェクトを派生させるか、名前空間またはテンプレートアロケーターパラメーターを使用します。なぜ、あなたは尋ねるかもしれません。プログラムが複数のファイルであり、STLまたは他のライブラリを使用している場合は、失敗するからです。

VS2005からのnew演算子の蒸留バージョンnew.cpp

void * operator new(size_t size) _THROW1(_STD bad_alloc)
{       // try to allocate size bytes
   void *p;
   while ((p = malloc(size)) == 0)
    if (_callnewh(size) == 0)
     {       // report no memory
        static const std::bad_alloc nomem;
        _RAISE(nomem);
     }

     return (p);
}
6
dirkgently

RE:

グローバルに新規/削除をオーバーロードしようとすることはありません

誰かがC++のあまり一般的ではない機能を使用しようとするときはいつでも、それは決して行われるべきではないように振る舞うのはなぜですか?

それは常に行われています、それは非常に一般的です、そして、私はこれをしなかった会社のために働きませんでした。

グローバルにオーバーロードされた新規および削除は、メモリ、メモリバグ、バッファオーバーランなどの追跡に非常に役立ちます。

彼らの正しい考えの誰も、数百万行のコードを持つプログラムを通過し、各クラスに新しいメンバーと削除メンバーを追加するつもりはありません。それはただの愚かです。

139
Dan

たぶん、あなたはちょっとしたプリプロセッサの魔法であなたが望むことをすることができます:

#include <iostream>

using namespace std;

void* operator new (size_t size, const char* filename, int line) {
    void* ptr = new char[size];
    cout << "size = " << size << " filename = " << filename << " line = " << line << endl;
    return ptr;
}

#define new new(__FILE__, __LINE__)

int main() {
    int* x = new int;
}
51
kyku

ここでの問題は、newのパラメータープロファイルが標準演算子newのパラメータープロファイルと一致しないため、1つが非表示にならない(したがってまだ使用されている)ことです。

新規および削除のパラメータプロファイルは、次のようにする必要があります。

void* operator new(size_t);
void operator delete(void*, size_t);
12
T.E.D.

オーバーロードされた演算子を正しく呼び出していますか?つまり、追加パラメーターを渡しますか?

4
zvrba

この問題は、オーバーロードされたnew演算子に追加した2つの引数に依存しています。何らかの方法でファイル名と行をグローバルにしてみてください(または、新しいクラスをオーバーロードして単一のクラスを削除する場合はメンバー変数)。それはもっとうまくいくはずです。

4
Benoît