Hi Rooters,
I’m writing a small macro like this
if()----->First if statement
{
TMultiGraph* stack = new TMultiGraph;
…
}
if()----->Second if statement
{
THStack* stack = new THStack;
}
When I run it, the code will crash, complaining “stack” already declared as different type.
I add two lines “delete stack; stack = NULL;” at the end of the first if statement, then program can work, but still giving out an error.
So My questions are:
Why is this case? I think that the two stacks are in different scopes.
How can I deal with the memory in ROOT? It seems the “delete stack; stack = NULL” has not deleted the object fully.
If I have defined several objects, like TH1*, TGraph*, TLegend*, do I really have to delete them? How can I do that? Sometimes deleting an object will cause a crash(not a NULL object).
I assume you’re using CINT here. I have found that the scoping rules are not the same as for standard C++ in CINT, so I’m not surprised by the problem you’re having.
Also, I think these days the accepted practice is to set pointers to 0 rather than NULL after a delete.
The code you have should work if you compile it. If you want to continue to use CINT for it, you should probably either come up with a different name for the second pointer or cast it to the correct pointer type before you allocate the memory the second time.
Now that I think more about it, I don’t think you could cast the pointer. However, if you’re using CINT you can simply let it allocate the pointers automatically. For example, using 2 different TH1 types:
bool select = true;
if (select) {
h = new TH1F("test", "test", 10, 0., 10.);
} else {
h = new TH1D("test", "test", 10, 0., 10.);
}
This will give you back h as either a TH1F or TH1D pointer. And yes, h will still be in scope after the if statement block.
Again, compiling is the best way to do things if you want to keep yourself within C++ scoping rules. Variable scoping in CINT is, to me at least, quite confusing.