Static pointers to histograms and adding operation

Dear ROOT developers,

I am using version 4.02/00 on RedHat Linux 9.
The following script causes a crash after executed 10 times or so.

— start —
#include “TH1.h”

TH1F *h;
TH1F *h2;
TH1F *h3;

void test()
{
if (h) h->Delete();
if (h2) h2->Delete();
if (h3) h3->Delete();

h = new TH1F(“h”, “”, 100, 0, 100);
h2 = (TH1F *) h->Clone(“h2”);
h3 = (TH1F *) h->Clone(“h3”);

// do something

*h3 = *h + *h2;

}
— end —

root [0] .L test.C++
Info in TUnixSystem::ACLiC: creating shared library /home/kameoka/macros/root/test_C.so
root [1] test()
root [2] test()
root [3] test()
root [4] test()
root [5] test()
root [6] test()
root [7] test()
root [8] test()
root [9] test()
root [10] test()

*** Break *** segmentation violation
Generating stack trace…
0x4121d5d8 in from /lib/i686/libc.so.6
0x401a2e68 in TList::Remove(TObject*) + 0x36 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x401a0d1a in THashList::Remove(TObject*) + 0x46 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x408ff899 in TH1::~TH1 not-in-charge + 0x141 from /usr/local/cern/root-4.02.00/lib/libHist.so
0x409141ab in TH1F::~TH1F in-charge deleting + 0x71 from /usr/local/cern/root-4.02.00/lib/libHist.so
0x40147d65 in TObject::Delete(char const*) + 0x41 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x41b9c62e in test() + 0x36 from /home/kameoka/macros/root/test_C.so
0x41b9c858 in from /home/kameoka/macros/root/test_C.so
0x407078e7 in G__call_cppfunc + 0x266 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406f6fde in G__interpret_func + 0x706 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406df1c5 in G__getfunction + 0x1954 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406d6176 in G__getitem + 0x5f1 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406d4d5e in G__getexpr + 0x783e from /usr/local/cern/root-4.02.00/lib/libCint.so
0x4071ca5e in G__exec_function + 0x1d5 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x407236ab in G__exec_statement + 0x23eb from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406bdf3b in G__exec_tempfile_core + 0x2ce from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406be118 in G__exec_tempfile_fp + 0x22 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x4072b93e in G__process_cmd + 0x45f7 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x401ac419 in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) + 0xa9 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4010bdec in TApplication::ProcessLine(char const*, bool, int*) + 0x670 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4109f069 in TRint::HandleTermInput() + 0x1dd from /usr/local/cern/root-4.02.00/lib/libRint.so
0x4109deda in TTermInputHandler::Notify() + 0x24 from /usr/local/cern/root-4.02.00/lib/libRint.so
0x4109f9e2 in TTermInputHandler::ReadNotify() + 0x12 from /usr/local/cern/root-4.02.00/lib/libRint.so
0x40235397 in TUnixSystem::CheckDescriptors() + 0x143 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x40234287 in TUnixSystem::DispatchOneEvent(bool) + 0x161 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4016f5a8 in TSystem::InnerLoop() + 0x18 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4016f54d in TSystem::Run() + 0x6f from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4010c860 in TApplication::Run(bool) + 0x32 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4109eb65 in TRint::Run(bool) + 0x327 from /usr/local/cern/root-4.02.00/lib/libRint.so
0x0804886d in main + 0x71 from /usr/local/cern/root-4.02.00/bin/root.exe
0x4120aa07 in __libc_start_main + 0xc7 from /lib/i686/libc.so.6
0x0804876d in _Unwind_Resume + 0x31 from /usr/local/cern/root-4.02.00/bin/root.exe

I feel that the combination of static pointers to histograms and adding operation for them is related to the problem.
Could you kindly tell me what is the point ?


Kame

Change your code to:
#include “TH1.h”

TH1F *h=0;
TH1F *h2=0;
TH1F *h3=0;

void kame()
{
if (h) delete h;
if (h2) delete h2;
if (h3) delete h3;

h = new TH1F(“h”, “”, 100, 0, 100);
h2 = (TH1F *) h->Clone(“h2”);
h3 = (TH1F *) h->Clone(“h3”);

// do something

*h3 = *h + *h2;

}

Rene

Thank you for your reply.

I modified the script as you told, but it also crashed after 7 times executions.

root [8] test()

*** Break *** segmentation violation
Generating stack trace…
0x4121d5d8 in from /lib/i686/libc.so.6
0x401a164a in THashTable::FindObject(TObject const*) const + 0x66 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x401a0d02 in THashList::Remove(TObject*) + 0x2e from /usr/local/cern/root-4.02.00/lib/libCore.so
0x408ff899 in TH1::~TH1 not-in-charge + 0x141 from /usr/local/cern/root-4.02.00/lib/libHist.so
0x409141ab in TH1F::~TH1F in-charge deleting + 0x71 from /usr/local/cern/root-4.02.00/lib/libHist.so
0x41b9c664 in test() + 0x6c from /home/kameoka/macros/root/test_C.so
0x41b9c84c in from /home/kameoka/macros/root/test_C.so
0x407078e7 in G__call_cppfunc + 0x266 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406f6fde in G__interpret_func + 0x706 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406df1c5 in G__getfunction + 0x1954 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406d6176 in G__getitem + 0x5f1 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406d4d5e in G__getexpr + 0x783e from /usr/local/cern/root-4.02.00/lib/libCint.so
0x4071ca5e in G__exec_function + 0x1d5 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x407236ab in G__exec_statement + 0x23eb from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406bdf3b in G__exec_tempfile_core + 0x2ce from /usr/local/cern/root-4.02.00/lib/libCint.so
0x406be118 in G__exec_tempfile_fp + 0x22 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x4072b93e in G__process_cmd + 0x45f7 from /usr/local/cern/root-4.02.00/lib/libCint.so
0x401ac419 in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) + 0xa9 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4010bdec in TApplication::ProcessLine(char const*, bool, int*) + 0x670 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4109f069 in TRint::HandleTermInput() + 0x1dd from /usr/local/cern/root-4.02.00/lib/libRint.so
0x4109deda in TTermInputHandler::Notify() + 0x24 from /usr/local/cern/root-4.02.00/lib/libRint.so
0x4109f9e2 in TTermInputHandler::ReadNotify() + 0x12 from /usr/local/cern/root-4.02.00/lib/libRint.so
0x40235397 in TUnixSystem::CheckDescriptors() + 0x143 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x40234287 in TUnixSystem::DispatchOneEvent(bool) + 0x161 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4016f5a8 in TSystem::InnerLoop() + 0x18 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4016f54d in TSystem::Run() + 0x6f from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4010c860 in TApplication::Run(bool) + 0x32 from /usr/local/cern/root-4.02.00/lib/libCore.so
0x4109eb65 in TRint::Run(bool) + 0x327 from /usr/local/cern/root-4.02.00/lib/libRint.so
0x0804886d in main + 0x71 from /usr/local/cern/root-4.02.00/bin/root.exe
0x4120aa07 in __libc_start_main + 0xc7 from /lib/i686/libc.so.6
0x0804876d in _Unwind_Resume + 0x31 from /usr/local/cern/root-4.02.00/bin/root.exe

Hi Kame,
this happens because you’re expecting the h, h2, h3 pointers to “survive” from one call to the next - but that’s not the case. When loading the library they will all be initialized to 0 (according to your lines 3…5), afterwards they wont. So next time you call the function kame(), h, h2, and h3 are uninitialized: they do not point to the histograms from the previous call to kame(). This is not a problem with Cint, it’s C(++) and thus a problem with your code. As a work-around, you can declare your histograms as static:

static TH1F *h=0; static TH1F *h2=0; static TH1F *h3=0;
Axel.

Hi,

Actually there is a problem in the TH1F copy constructor.
To work around the problem use

h3->SetDirectory(0); *h3 = *h + *h2;
Note that the result of this code is to have being in a state similiar to having done

*h3 = *h; h3->Add(h2);
In particular, h3 is now named 'h" and not ‘h3’.
To preserve the name you should use

Cheers,
Philippe.

Hi Axel,
thank you for your reply.

I don’t think this is wrong C++ code.
If h, h2, h3 are automatic variables, you are right.
But the variables declared out of functions should be always “static” as well as local variables with “static” modifiers,
and C/C++ guarantee to initialize static variables to 0 at the begining of the program.
Actually, the crash occurred although I added “static” modifiers to h, h2, h3.
Am I wrong?


Kame

Hi Kame,

[quote=“kame”]I don’t think this is wrong C++ code.[/quote]No, it’s a wrong reply. Sorry about that! As Philippe pointed out, it was a problem with ROOT.
Cheers, Axel.

Hi, Philippe.
Thank you for your reply.

I modified the script according to your instruction,
and the problem seems to be fixed.

Thank you very much!

Please note that the original problem has been solved in the CVS repository.

Cheers,
Philippe