Hi Ben, The problem comes from the use of incompatible pair of new and delete operator. You have: data::~data() { delete [] array; } void data::SetArray() { ... delete array; ... array = new short[fArraySize]; Note that the delete in SetArray is expecting to delete only ONE entity (i.e. only one short!). Changing the delete in SetArray to be the same as the one in the destructor should fix the problem. In other word, when allocating memory as an array, you need to always delete it as an array [delete [] array;] Cheers, Philippe. -----Original Message----- From: owner-roottalk@pcroot.cern.ch [mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Ben Morgan Sent: Friday, March 01, 2002 7:53 AM To: roottalk@pcroot.cern.ch Subject: [ROOT] A very strange TTree problem Hi ROOTers, I'm encountering a strange problem when trying to store a class in a TTree. The problem appears to be with the 1D dynamic array data member that I'm using. In the application program (see below), the class (and array) can be generated and the values of the array printed to the screen no problem within the for loop. However, when I add the lines which generate the TTree and TBranch, the array is generated on the first pass through the loop, but the app then falls over on the second pass through the loop with a segmentation violation. I've done some investigation on this and it appears that the fault originates with the 'delete array' statement in the SetArray() method of the class (see below). However, I cannot understand why this causes the problem, as the code is just adapted from the Event example in the manual. Also, I've written another class with identical coding for dealing with dynamic arrays that works no problem. Can anyone resolve the problem - I admit it's probably my coding.....? (I'm using ROOT v3.01/06 on a PC running RH6.2). Thanks, Ben Morgan. -Class data header- #ifndef __data_h #define __data_h #include<iostream.h> #include "TObject.h" #include "TRandom.h" class data : public TObject { private: Int_t fNwire; Int_t fNchan; Int_t fArraySize; Short_t *array; //[fArraySize] public: data(); virtual ~data(); void SetWC(Int_t a, Int_t b) {fNwire=a; fNchan=b; fArraySize=a*b;} void SetArray(); void Display(); ClassDef(data,1) }; #endif -Class data implementation- #include "data.h" ClassImp(data) data::data() { fNwire=0; fNchan=0; array=0; } data::~data() { delete [] array; } void data::SetArray() { cout<<"In SetArray"<<endl; delete array; cout<<"Deleted Array"<<endl; if(!fArraySize) { array=0; return; } array = new short[fArraySize]; cout<<"Created new array"<<endl; for(Int_t i=0; i<fNwire; i++) { for(Int_t j=0; j<fNchan; j++) { array[i*(fNchan+1)+j] = (Short_t)(i+j); } } } void data::Display() { cout<<"\n"; cout<<"fArraySize = "<<fArraySize<<endl; for (Int_t i=0; i<fNwire; i++) { for(Int_t j=0; j<fNchan; j++) { cout<<array[i*(fNchan+1)+j]<<" "; } cout<<endl; } } -Application using data class- #include <iostream.h> #include <stdlib.h> #include "TROOT.h" #include "TFile.h" #include "TTree.h" #include "TBranch.h" #include "data.h" int main(int argc, char *argv[]) { TFile *dfile = new TFile("datatree.root", "RECREATE"); TTree *tree = new TTree("RawData", "A Tree with data Objects"); data *d1 = new data(); TBranch *branch = tree->Branch("data_branch","data", &d1,16000,2); for(Int_t i=0; i<10; i++) { d1->SetWC(8,10); d1->SetArray(); //Falls over here on second pass through loop d1->Display(); tree->Fill(); } tree->Print(); dfile->Write(); dfile->Close(); delete d1; return 0; } -- ------------------------------------------------------------------------------- Mr. Ben Morgan Postgraduate Student University of Sheffield Department of Physics & Astronomy Hicks Building Hounsfield Road Sheffield S3 7RH -------------------------------------------------------------------------------
This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:50:43 MET