Re: [ROOT] TCanvas and memory trouble

From: Rene Brun (Rene.Brun@cern.ch)
Date: Tue Jul 17 2001 - 08:32:41 MEST


Hi Matthieu,

Two problems in your logic:
 - c1 = TCanvas*[nHistos]; should be c1 = new TCanvas*[nHistos];
 - If you delete a canvas with the window manager button or the menu, the list
   of ROOT canvases is correctly updated and the TCanvas object deleted.
   However, your pointer now points to a deleted object -> your problem.

There is a way to have the control when an object (derived from TObject)
is deleted. You can register your own cleanup object to the list of CleanUps
in Root. When a TObject is deleted, the function RecursiveRemove of all objects
registered in the CleanUps is called with as argument the pointer to the object
being deleted. 
You can implement a MyCanvasHandler class with the logic in your macro
in the constructor. In the constructor, do:
  gROOT->GetListOfCleanUps()->Add(this);
Implement MyCanvasHandler::RecursiveRemove , scan your list of pointers to
canvases, if one is equal to the argument, set to 0 the pointer.

Rene Brun


Matthieu Guillo wrote:
> 
> Hello Rooters
> 
> I have some trouble managing memory with TCanvas objects.
> I have an array of TCanvas that I dynamically allocate (the size is not
> known at run time). So I do;
> 
> TCanvas** c1 = NULL;
> .......................
> // the size of the array is now known, it is "nHistos"
> 
> c1 = TCanvas*[nHistos];
> for (int i = 0; i < nHistos; i++) {
>     char  szPadName[10];
>     sprintf(szPadName, "c%d", i + 1);
>     c1[i] = new TCanvas(szPadName, szPadName, 10 + 20 *
> i, 10 + 20 * i, 750 + 20 * i, 940 + 20 * i);
> }
> 
> This works fine, I can use the canvas without trouble. But when I try to
>  delete them and free the memory:
> 
> if (c1) {
>   for (int i = 0; i < nHistos; i++) {
>     if (c1[i]) {
>       delete c1[i];
>       c1[i] =  NULL;
>     }
>   }
>   delete[] c1;
> }
> 
> This works also fine, except after I have deleted a canvas using the mouse
> on the x button. Then everything crashes. Obviously ROOT makes some
> housekeeping I don't know and all some of my pointers are now dangling.
> 
> How can I solve this problem? I tried also to use the gROOT pointer and
> the GetListOfCanvases() as in:
> 
> if (gROOT->GetListOfCanvases()->FindObject(c1[i]->GetName())) {
>   delete c1[i];
> }
> 
> but this doesn't help since the problem seems to be with the pointer c[i]
> itself.
> 
> Thanks a lot.
> 
> Matthieu Guillo
> University of South Carolina
> Thomas Jefferson National Laboratory
> Office 71 trailer 16
> Phone: 757-269-5551



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