2017-09-08 9 views
-1

マルチスレッド環境でnew演算子をオーバーロードし、その中にスレッドID、関数名、行番号を入れたいとします。これを行う方法はありますか?C++オーバーロードされた "new"演算子の行番号と関数名を取得する方法

+2

http://en.cppreference.com/w/cpp/experimental/source_locationがあるまでは、MACROを使用する必要があります。 – Jarod42

+0

[C/C++行番号](https://stackoverflow.com/questions/2849832/cc-line-number)の可能な複製 – user463035818

+0

オペレータでこれを実行しようとすると、常に名前と行番号が取得されますここで 'operator new'が定義されていて、それが呼び出される場所ではありません。 –

答えて

2

新しいoperator newオーバーロードすることができます:

void * operator new(std::size_t count, const char* file, int line) 
{ 
    // Do stuff 
    // ... 
    return ::operator new(count); 
} 

void * operator delete(void* p, const char* file, int line) 
{ 
    // Do stuff 
    // ... 
    return ::operator delete(p); 
} 

// ... and [] versions .. 

その後、プレースメントの構文を使用することができます

auto x = new (__FILE__, __LINE__) Foo; 

をそしてマクロを追加することができます。一般的には

#define TRACE_NEW new (__FILE__, __LINE__) 

auto x = TRACE_NEW Foo; 
+0

いいえ、あなたは* placement new *をオーバーロードしていませんが、単純にグローバルな 'operator new'を追加し、' TRACE_NEW'でそれを使用しています。 [placement new](http://en.cppreference.com/w/cpp/language/new)は、たとえば'void * p = mmap(' .... '); auto x = new(p)Foo; ' –

+0

@BasileStarynkevitchうん、" placement new "が間違っていた。スタンダードは、「配置割当機能」と呼んでいるが、明らかに同じものではない。おそらく、この言葉遣いが良いでしょう。 – molbdnilo

0

をあなたが望むことをする方法はありません(もちろん、moldbnilo answeredのようなマクロを使うことを除いてあなたは、最近のLinuxシステム上で、すべてのコード(及び場合はライブラリのほとんどデバッグオプションでコンパイルされている)libstdc++を含めて、使用している場合、私は将来std::source_location

しかし、あなたはまた、イアン・テイラーのlibbacktraceを検討するかもしれません(GCCの内部でも使用されています)、operator new実装内で使用してください。そのlibbacktracecall stackのコールフレームを検査し、DWARFデバッグ情報を使用することができます。

あなたはcall stack(特に発信元の場所はoperator new)のほとんどの機能のソースの場所を持つことさえできます。

あなたは両方のデバッグ情報(例えば-g)といくつかの最適化フラグ(例えば-O1または多分-O2)と(GCCまたはClangを使用して)いくつかのC++コードをコンパイルすることができますことを覚えておいてください。もちろん、デバッグ情報(DWARF)は "あいまい"であるかもしれませんが、実際にはほとんどの場合は実際に使用することができます。

ところで、おそらくvalgrindか、-fsanitize=addressinstrumentation optionでコンパイルすることで消毒する必要があるかもしれません(あなたの疑問が動機付けされていないためわからない)。

関連する問題