web-dev-qa-db-ja.com

グローバルなnew演算子とdelete演算子を適切に置き換える方法

まず第一に、SOに関する同様のトピックを持つ少なくとも4〜5のトピックがありました。私はそれらをそれぞれ読みましたが、この特定の問題について彼らが本当に私を助けているとは感じません。他の誰かが重複した質問を見つけた場合、私は謝罪します。非常に一般的な質問のように思えるので、これを投稿する前に検索のシェアをしました。

Windows 7でVisual Studio .NET 2003を使用しています。

診断のためのmalloc()およびfree()への独自のカスタム呼び出しを指す、独自のnew/deleteのオーバーロードがあります。私の新規/削除のオーバーロードは、いくつかのファイルに含めたヘッダーファイルにあります。

問題は、コードベースがほとんどスパゲッティであり、これらのオーバーロードをすべてに確実に使用できるようにする簡単な方法がないことです。ブラックボックスであるサードパーティライブラリへのインクルードがあります。また、どこでもSTLを使用しています。

私のテストでは、STLがまだ自分のnew/delete呼び出しと標準のMSVC new/delete呼び出しへの呼び出しを混合していることがわかりました。

ヘッダーファイルを他の何千ものファイルに含めるのは現実的ではないように思われますが、これには時間がかかりすぎます。誰でも新しい/削除をグローバルに適切かつ効果的にオーバーロードし、すべてがカスタムメモリマネージャーを使用する方法に関するヒントを提供できますか?

54
void.pointer

それはこれがどのように機能するかではありません。 replace 2つの演算子であり、これはlink時に行われます。あなたがする必要があるのは、単一のTU thatdefinesこれらの演算子を書き、それをミックスにリンクすることです。他の誰もこれについて知る必要はありません:

_// optional_ops.cpp

void * operator new(std::size_t n) throw(std::bad_alloc)
{
  //...
}
void operator delete(void * p) throw()
{
  //...
}
_

原則として、これらの関数(_operator new_、_operator delete_)を宣言するヘッダーファイルは必要ありません。これら2つの関数の宣言は既にハードコードされているためですあなたがするなら、言語に。ただし、std、_std::bad_alloc_、および_std::size_t_という名前はnot事前宣言されているため、おそらく_<new>_を含める必要があります。またはそれらの名前を提供する他のヘッダー。

C++ 11以降では、代わりにdecltype(sizeof(0))を使用して、どのような種類のライブラリも必要としない方法で最初のパラメーターのサイズを取得できます。 C++ 11には、動的な例外仕様のない、より単純な例外モデルもあります(最終的にC++ 17で完全に言語から削除されました)。

_void * operator new(decltype(sizeof(0)) n) noexcept(false)
{
  //...
}
_
75
Kerrek SB

次の行も追加します。

void *operator new[](std::size_t s) throw(std::bad_alloc)
{
    // TODO: implement
    return NULL;
}
void operator delete[](void *p) throw()
{
    // TODO: implement
}
34
Extrunder