- ベストアンサー
newされたポインタとdeleteされるポインタが…
いま私は、std::mapを使って、newされたポインタ(メモリの先頭アドレス)をkeyとして記録し、newされた場所のファイルや行番号、サイズ、何回目のnewか、などなどをvalueとして構造体にまとめて保存してデバッグなどに役立て、deleteされると同時にこの情報を破棄し、最後にすべて破棄されているかどうかを調べる(メモリリークのチェック)という機構を作っています。 ですが、keyとなっているメモリのアドレスは、多重継承や仮想継承とキャストの組み合わせ次第では、newされた時点のものとdeleteされる時点のもので異なっている場合があるため、情報を破棄することができず、行き詰ってしまいました。(無論、delete以外にも情報を引き出す際に影響が…) deleteするポインタから、そのポインタがnewで作成されたときのメモリの先頭アドレスを求める方法はないでしょうか? 以下に問題の部分だけ抽出したようなコードを挙げます。 ---------------- #include <stdio.h> class CLS1{ public: int x,y,z; virtual ~CLS1(){} }; class CLS2{ public: int x,y; virtual ~CLS2(){} }; class CLS3:public CLS1, public CLS2{ public: int x; virtual ~CLS3(){} }; void print(void* p){printf("%p\n",p);} template<typename T> T* create(T* p){ // ここで、たとえば 00854880 と記録されたとして… print(p); return p; } template<typename T> void releace(T* p){ // ここでも 00854880 と記録されてほしいが、 // 00854890 と記録されてしまう。 // この場所で 00854880 と同じインスタンスであることを確かめる方法はないでしょうか? print(p); delete p; } int main(){ CLS2* x = create(new CLS3); // 多重継承しているため、 00854890 と記録される。 print(x); release(x); return 0; }
- みんなの回答 (4)
- 専門家の回答
お礼
boost使うなら #include <boost/type_traits/is_polymorphic.hpp> #include <boost/utility/enable_if.hpp> template<typename T> void* getNewMemStartPos(T* x, typename boost::enable_if< boost::is_polymorphic<T> >::type* =0){ return dynamic_cast<void*>(x); } template<typename T> void* getNewMemStartPos(T* x, typename boost::disable_if< boost::is_polymorphic<T> >::type* =0){ return static_cast<void*>(x); } template<typename T> void release(T* p){ print(getNewMemStartPos(p)); delete p; } とか考えましたが… boost使わない方法はない…かな、やっぱ。 仮想関数を持たないクラスを多重継承したようなクラスには残念ながら対応できませんが、しょうがないですね。 当初の質問内容からも若干方向がずれてきましたので、とりあえずこれで締め切らせていただきます。 回答者の皆さんには、厚くお礼申し上げます。