// // Run this in ROOT with // // Root> .x bar.cxx++ // // Or compile it into a program with (on GNU/Linux) // // prompt% g++ `root-config --cflags --libs` bar.cxx -o bar // #ifndef __CINT__ #ifndef ROOT_TObject #include "TObject.h" #endif #ifndef ROOT_TObjArray #include "TObjArray.h" #endif #ifndef ROOT_TObjectTable #include "TObjectTable.h" #endif #ifndef __IOSTREAM__ #include #endif #ifndef __IOMANIP__ #include #endif #endif // __CINT__ class C1 : public TObject { private: Int_t fInt; public: C1(Int_t i=0) : fInt(i) {} virtual ~C1() { cout << "Deleting C1 at " << hex << this << endl; } void Print(Option_t* option="") const { cout << "C1 object: " << fInt << " " << hex << this << endl; } } ; class C2 : public TObject { private: C1* fC1; public: C2(C1* c1=0) : fC1(c1) {} // ~C2() { delete fC1; } virtual ~C2() {} C1* GetC1() const { return fC1; } void Print(Option_t* option="") const { cout << "C2 object: " << hex << fC1 << endl; } } ; void bar() { cout << "Create array with 5 C1 objects in it" << endl; // gObjectTable->Print(); TObjArray array; for (Int_t i = 1; i <= 5; i++) array.Add(new C1(i)); array.Print(); cout << "Making a C2 object and deleting it" << endl; C2* c2 = new C2((C1*)array.At(3)); c2->Print(); cout << "Will get SIGSEGV here if C2::~C2 deallocates pointer" << endl; array.Print(); // gObjectTable->Print(); cout << "Cleaning up the array" << endl; array.Delete(); array.Print(); // gObjectTable->Print(); C1* c1 = c2->GetC1(); if (!c1) cout << "No C1 object in c2 " << hex << c1 << endl; else { cout << "Found C1 object in c2 " << hex << c1 << endl; cout << "The program should get SIGSEGV here" << endl; cout << "It's a " << c1->ClassName() << endl; c1->Print(); c1->Dump(); } // gObjectTable->Print(); delete c2; } #ifndef __CINT__ int main() { bar(); return 0; } #endif