RE: [ROOT] Little hint about pointers

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Wed Nov 21 2001 - 12:57:44 MET


Hi Philippe, 

On Tue, 20 Nov 2001 17:46:14 -0600
Philippe Canal <pcanal@fnal.gov> wrote
concerning "RE: [ROOT] Little hint about pointers":
> Hi Christian,
> 
> > Well, as the attached (expanded) example show, it does call the DTOR
> > of class C1. For what ever reason, the underlying TObject array is
> > still there :-(.  This seems extreemly odd.  The program should
> > SIGSEGV. 
> 
> I supposed you meant that the C1 object in C2 seems to still be there.
> This is actually a behavior that __might__ happen under standard C++
> rule.

No, I meant a TObject.  Look at the output of the Print message.  It's
TObject::Print that is reached, _not_ C1::Print.  It's even more
evident when sending the message ClassName.  So all in all, it's
probably a completly new object. 

> When you delete an object, its destructor is executed and its memory is
> marked as free to be reused.  UNLESS this memory is actually reused (by
> some new memory allocation for example), the memory where the object 
> used to be is still in the exact same state as at the end of the destructor.

Unless, ofcourse, that the DTOR explicitly memcpy zeros all over
itself :-) FYI, I'm not sure that would work.  

> Thus it is very often the case that just after 'delete myobject;' you can
> still use it without segmentation fault (however, there is no guarantee of
> that)

Refering to the ANSI/ISO C++ standard, section 3.7.3.2, paragraph 4,
where it says: 

  ... the deallocation function [operator delete] shall deallocate the
  storage referenced by the pointer, rendering invalid all pointers
  refering to any part of the deallocated storage.  

Now what is meant by "invalid" is really the question. The paragraph
continues:

  The effect of using an invalid pointer value ... is
  undefined[footnote]. 
  
  footnote: On some implmentations, it causes a system-generated
  runtime fault.	    

I read the footnote as saying: it should cause a SIGSEGV.  I'm
probably reading it wrong, 'cause apperantly the GCC fellows read as
you did too. 

Anyway, I don't really think this is the problem in the first case.  I
think what happens, is that a new TObject object is created at the
same address as where the C1 Object was. 

> As you probably know, in your example the test:
> 
>   C1* c1 = c2->GetC1(); 
>   if (!c1) 
> 
> is guaranted to always say that c1 is still there, since (in the
> small program you sent) there is NO provision for c2 to learn of the
> demise of C1.   

The if should be true, yes, since c2 still holds the address of the
old C2 object.  However, I think it's odd that it finds a TObject at
the same address. C1 is after all a subclass of TObject, not the other
way around. 

BTW, I think the original problem of memory leak can be solved by
deleting the TObjArray.

Yours, 

Christian Holm Christensen -------------------------------------------
Address: Sankt Hansgade 23, 1. th.           Phone:  (+45) 35 35 96 91 
         DK-2200 Copenhagen N                Cell:   (+45) 28 82 16 23
         Denmark                             Office: (+45) 353  25 305 
Email:   cholm@nbi.dk                        Web:    www.nbi.dk/~cholm



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:51:09 MET