4

のオーバーライドをバイパスする方法はありますoperator newか?

このようなもの:

void* ::operator new( std::size_t size ) {
    void *p = ( ::operator new( size ) );  // But original, _not_ infinite recursion
    // do stuff with p
    return p; 
}

背景: 私は最近、Visual Studio 2012 でコンパイルするように切り替えたレガシー コードをいくつか持っています。十分なメモリ ブロックにmalloc失敗すると、ランダムにクラッシュします。_heap_alloc(はい、コードには小さなメモリ リークやその他の悪い動作が散りばめられています。しかし、残念ながら完全なクリーンアップは現実的ではありません。500 000 SLOC 程度です。)

私の現在の理論では、原因は、ほとんどすべてのソース ファイルに、次のオーバーライドを持つヘッダーが含まれていることですoperator new

void* ::operator new( std::size_t size ) {
    void* p = malloc( size );
    if( p == NULL )
        throw;
    // set memory to zero
    memset( p, 0, size );
    return p;
};

void* ::operator new[]( size_t count ) throw(std::bad_alloc) {
    // try to allocate count bytes for an array
    return (operator new(count));
}

のオーバーライドはありませんdelete

本質的に、これは、アプリケーションが の代わりに を使用mallocした割り当てと解放を使用することを意味します。deletefree

delete最初に Q&D 修正を試みます:その usesのオーバーライドを導入しますfree。しかし、これは部分的にしか役に立ちません。順序を含めたり、リンクされたライブラリが混乱したりすることがあるためです。

2 回目の Q&D 修正の試行: オーバーライドを削除します。残念ながらメモリを 0 に初期化する必要があります。常にそれを行っていた古いコンパイラからの遺産、およびC++が常にそれを行うと想定したコーダー。

new() がそれを処理することは承知していますが、残念ながら、手動ですべてのソース コードを調べて更新することなく、それを利用する良い方法を知りません。また、コンストラクターでそれを行わずにすべてのメンバーを無効にすることを想定している、実装が不十分なクラスには役立ちません。

したがって、Q&D 修正の 3 番目のアイデアは、この質問が尋ねるように、オーバーライドで通常の new を使用することです。

4

1 に答える 1

2

operator new のオーバーライドをバイパスする方法はありますか?

私が知っているものはありませんが、MS が _heap_alloc ベースの実装で行ったのと同じ方法でカスタム関数に再実装し、カスタマイズを追加してみませんか?

いずれにせよ、1 回の do-or-die 割り当て試行のみは、MS が行うことではありません。

http://msdn.microsoft.com/en-us/library/vstudio/we2zys4d.aspx

デフォルトの動作は、ループを実行することです。ループ内で、関数は最初に要求されたストレージの割り当てを試みます

とにかく-nmがコメントに入れたものを2番目に

実メモリのバグを修正する必要があります

それは自明です。これらのデバッグ目的のために - pls は std::set_new_handler を見てください。

ところで-あなたのコードについてイライラすることがいくつかあります

  • 演算子の明示的な資格
  • std::bad_alloc をスローするのではなく、キャッチ ブロックの外側で再スローする

ハッピーハッキング!

よろしく、S.

PS:@all: ここでの経験が限られているため、その質問に「投票」することはできませんが、そうすることをお勧めします。これは非常に興味深いトピックであり、よくまとめられています。

于 2013-05-14T11:27:30.250 に答える