Re: Writing and reading objects from a file... don't read back the same way...

Rene Brun (Rene.Brun@cern.ch)
Fri, 24 Oct 1997 17:30:40 +0200


Gordon,
Thanks for providing this simple test. It was easy to trace the
problem. When using the split mode, arrays with a constant
number of elements (in your case you have a member _item[2])
were simply not written to any branch.
The fix was very simple: deleting one line in TTree::Branch.
This will be part of the version 1.03/06.

Rene Brun

Gordon Watts (Brown University) wrote:
>
> Hi,
> Ok, I've been careful to isolate the problems I've been having this time.
> So, while it is likely something I am doing, I can reproduce the behavior
> in a small example program I've included below. Basically, it would seem
> that when I write out an object and then read it back in, some of the
> values read back in aren't put in the correct spot. This happens only when
> split level = 1, not zero. I am using Windows NT 4.0, with MSVC 5.0 (not
> 4... if this isn't a bug in my code one of my first guesses will be an
> incompatibility between 4.0 and 5.0 object layouts...>?).
>
> First, the macro I use to run the test. Right below it is the output it
> produces on my windows nt maching. I'm using root 1.03/05, btw:
>
> ------------ dump_out_test.cpp ----------------------------------------
> {
> gROOT -> Reset();
>
> TFile output_file ("output.stuff", "RECREATE", "Junk");
>
> TTree *output_tree = new TTree ("T", "Stuff", 1024);
>
> B *event = new B;
>
> output_tree -> Branch ("event", "B", &event, 2048, 1);
>
> if (!output_tree)
> cout << "No output tree!" << endl;
>
> for (int i = 0; i < 10; i++) {
> output_tree -> Fill();
> }
> event->Dump(); // What we think we wrote
>
> output_file.Write();
> // output_tree -> Print();
> output_file.Close();
>
> gROOT -> Reset();
>
> TFile ("output.stuff");
> TBranch *b = T.GetBranch("event");
> B *event;
> b->SetAddress(&event);
> b->GetEvent(1);
> event.Dump(); // What we read!
> return 0;
> }
> ---------------- Output of this maco on my Windows NT machine.
> ------------------
>
> Processing dump_out_test.cpp...
> _the_a_obj._item[2] 0
> _the_a_obj.fUniqueID 0 object unique identifier
> _the_a_obj.fBits 50331648 bit field status word
> fUniqueID 0 object unique identifier
> fBits 50331648 bit field status word
> TFile Writing Name=output.stuff Title=Junk
> _the_a_obj._item[2] 0
> _the_a_obj.fUniqueID 50331648 object unique identifier <<<<<<<<<<
> Huh?
> _the_a_obj.fBits 0 bit field status word
> fUniqueID 50331648 object unique identifier <<<<<<<<<<
> <
> Huh?
> fBits 50331648 bit field status word
>
> If I set splitlevel to be "0" when I write out, then fUniqueID is zero,
> just as it is when
> it is written out.
>
> I much more complex programs I see this sort of behavior happening to my
> data members (floats or integers are overwritten with the 50331648 number).
>
> -------------- The LinkDef.h
> -------------------------------------------------
> //
> // Stuff for CINT
> //
>
> #ifdef __CINT__
>
> #pragma link off all globals;
> #pragma link off all classes;
> #pragma link off all functions;
>
> #pragma link C++ class A;
> #pragma link C++ class B;
> #endif
>
> -------------- test.h file
> ---------------------------------------------------------
>
> #include "TObject.h"
>
> class A : public TObject {
>
> private:
> float _item[2];
>
> public:
> A (void) {_item[0] = 0; _item[1] = 0;};
>
> ClassDef (A,1) // The A Class
> };
>
> class B : public TObject {
> public:
> A _the_a_obj;
>
> B (void) {};
> A &get_A (void) {return _the_a_obj;};
>
> ClassDef (B,1) // The B class
> };
>
> ---------------- test.cpp file
> -------------------------------------------------
>
> #include
> "test.h"
>
> ClassImp(A)
> ClassImp(B)
>
> ---------------------------------------------------------------------------------
>
> I have not been able to check this in UNIX, and I do not have access to the
> MSVC 4.0 compilers to see if that is the real cause here...
>
> Cheers,
> Gordon.