ROOT and Parentheses

At work I was recently tasked with making some simple plots to break down some data we recently collected. It turned out to be a bit annoying because some key metadata is omitted from the files, but since it's a small job I just hard coded my script with the necessary information. A few minutes of typing and I was ready to run it, which I did, only to be greeted with ROOT's ever-friendly *** Break *** segmentation violation. Here's a listing of the key bit of my program1:

vector<simpleFlasherSubrun> subruns;
subruns.push_back(simpleFlasherSubrun(1,63,27,point(-66.700, 276.920,   54.190)));
subruns.push_back(simpleFlasherSubrun(3,63,38,point(-66.700, 276.920, -138.040)));
subruns.push_back(simpleFlasherSubrun(5,63,56,point(-66.700, 276.920, -439.420)));
const unsigned int nSubruns=subruns.size();
cout << nSubruns << " subruns to process" << endl;

cout << "creating histograms" << endl;
TH1I** hitDistHists = (TH1I**)malloc(nSubruns*sizeof(TH1I*));
for(int k=0; k<nSubruns; k++){
    stringstream prefix(ios::out);
    prefix << "Subrun " << subruns[k].subrunNumber;
    cout << "prefix is \"" << prefix.str() << "\"" << endl;
    hitDistHists[k]=new TH1I((prefix.str()+"_hitDist").c_str(),
                             (prefix.str()+" Number of Hits versus Distance from Flasher OM").c_str(),
                             100,0,1000));
    cout << "hit distance histogram is " << hitDistHists[k] << endl;
}

This is just the initialization, where I create some hardcoded data structures to describe the sections I want to break the data down into and then create some histogram objects which will become the actual plots once filled with data. The crash occurs later in the main body of the program when it tries to put data into one of the histograms. The reader will notice that I've tossed in a print statement which prints out the value of the newly set histogram pointer, which I did because I was suspicious about whether I was getting valid pointers at all. Indeed I was not, here's what the script's output showed:

3 subruns to process
creating histograms
testHist is 0xa8b2f0
prefix is "Subrun 1"
hit distance histogram is 0xa8b1b0
prefix is "Subrun 3"
hit distance histogram is 0x3bc5c346b8
prefix is "Subrun 5"
hit distance histogram is 0x130

The first pointer looks okay, the second is a little odd, and the third I don't believe is valid for an instant. The mistake is in fact in the code I gave above, but i bet you'll never guess what it is.

Ready? Okay, look really closely at the end of the line that uses the new operator to create a histogram. Is there an extra parenthesis there? There can't be since the script ran and only crashed after that point, right? Wrong. There is and extra parenthesis and the line is being executed anyway, just that it somehow then produces bad pointers which only cause a crash later. Removing that one extra character makes the entire thing work exactly as it should. Now if the interpreter would actually check the script's syntax before executing it, maybe I wouldn't have had, oh, a few days of my time wasted by this dumb typo?


  1. The reason I'm using malloc there to create my array of pointers is that ROOT doesn't like the STL very much, so one of my first changes was to replace my use of std::vector<TH1D*> with a simple TH1D**. I probably didn't need to but it doesn't really hurt anything, either. 

No Comments

Comment on this post