4

Microsoft 標準ランタイムは割り当て関数のデバッグ バージョンを提供しますが、実際には機能しません。C++ コードでネイキッド new を使用することは想定されていないため、インストルメンテーションは標準ライブラリを指すか、標準ライブラリをインストルメントできないためどこにもポイントしません。

これで、割り当てのバックトレースを生成 (および記録) できるコードができ、DUMAも使用しました。ただし、ストリームを使用した場合、割り当て関数を置き換える試みは失敗しました。これstreambufは、いくつかのデバッグバリアントへの呼び出しが、new と delete の間で一貫性がないためです。

Microsoft標準ランタイムで、いプリプロセッサのトリックではなく、関数をオーバーライドすることにより、アロケータを置き換えた経験がある人はいますか? デバッグ アロケータを回避する必要があると思われますが、明らかな理由で定義を維持したいと考えてい_DEBUGます (より多くのデバッグ コードがそれに依存しています)。

注: 現在、Visual C++ 9.0 (Visual Studio 2008) に固執しています。

編集: C++ 標準ライブラリは、割り当てが 1 つによって行われる可能性があるため、ライブラリにコンパイルされた関数とインスタンス化、およびユーザー コードで生成されたインスタンス化との間で、new と delete の一貫した定義を持つ必要があるため、デバッグ アロケータを回避することはほとんどありません。他の人によって解放されます。ちなみに、force-included ヘッダーで静的なインライン バリアントを定義しても、うまくいかない可能性があります。

Edit2: Windows は特定の DLL からシンボルをバインドするため、動的リンクでは不可能です。そのため、リンク時にそれらをオーバーライドする方法はありません。ただし、動的リンクは必要なく、使用しません。これは、プライマリ ターゲットが WinCE であり、静的リンクがデフォルトであるためです。

4

1 に答える 1

1

これを行う方法は次のとおりです(jemallocを使用しますが、他のアロケーターも可能です):

  1. カスタム メモリ アロケータを C スタティック ライブラリとして個別にコンパイルします。
  2. C++ アプリケーションをカスタム アロケーター ライブラリにリンクします。
  3. new演算子をオーバーライドdeleteし、C++ アプリケーションでカスタム アロケーターを呼び出します。

ノート:

  • カスタム アロケータは、C++ ではなく C で記述する必要があります。
  • アロケータが別のライブラリに存在しない限り、アロケータを十分に早期に初期化することはできません。
  • mallocandのオーバーライドfreeも可能ですが、MSVC ではより困難です。これらは「弱い」リンクではなく、MSVC には多くのカスタム バリアントがある (たとえば、/FORCE:MULTIPLEリンカー フラグを使用する) ためです。

サンプルコード:

void* operator new(size_t size)
{
  void* ptr = my_malloc(size);
  if (ptr)
    return ptr;
  else
    throw std::bad_alloc();
}

void* operator new[](size_t size)
{
  void* ptr = my_malloc(size);
  if (ptr)
    return ptr;
  else
    throw std::bad_alloc();
}

void* operator new(size_t size, const std::nothrow_t&) throw()
{
  return my_malloc(size);
}

void* operator new[](size_t size, const std::nothrow_t&) throw()
{
  return my_malloc(size);
}

void operator delete(void* pointer) throw()
{
  my_free(pointer);
}

void operator delete[](void* pointer) throw()
{
  my_free(pointer);
}

void operator delete(void* pointer, const std::nothrow_t&) throw()
{
  my_free(pointer);
}

void operator delete[](void* pointer, const std::nothrow_t&) throw()
{
  my_free(pointer);
}
于 2016-12-09T10:29:02.540 に答える