Hi Philippe,
the streamer is not forgetting to 'clean' the vector. The specs don't
require a streamer to clean any containers before reading. To allow this
extension of the specs (so users could count on it) would
require remaking all streamers in a not always trivial way (and would also
introduce a performance overhead for the many cases where it is not needed).
If a user wants to reuse an object without delete/new one should implement
the Clear() method which should then be called before reusing the object.
Cheers, Fons.
On Fri, Aug 11, 2000 at 11:14:34AM -0500, Philippe Canal wrote:
> Hi,
>
> As you noted the streamer automatically created by rootcint is forgetting
> to 'clean' the vector before reading the streamer.
>
> For greater flexibility a Streamer should not assume that the object it
> is reading is clean and should insure clean-up. (To allow loop like
> in the Y::Streamer).
>
> This problem should be fixed shortly in the cvs repository.
>
> Philippe.
>
> > -----Original Message-----
> > From: owner-roottalk@pcroot.cern.ch
> > [mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Matevz Tadel
> > Sent: Tuesday, August 08, 2000 9:10 AM
> > To: roottalk@pcroot.cern.ch
> > Subject: [ROOT] streamers for nested stl containers
> >
> >
> > Hi,
> >
> > Imagine a situation:
> >
> > X.h <<fnord
> > #ifndef _x_h_
> > #define _x_h_
> >
> > #include <TNamed.h>
> > #include <vector>
> > #include <iostream>
> >
> > class X : public TNamed {
> > public:
> > vector<int> mV;
> >
> > X(const Text_t* n="x") : TNamed(n,0) {}
> > void Populate(Int_t M=3) { for(int i=0; i<M; i++) mV.push_back(i); }
> > void Spit() {
> > cout << GetName() <<": [";
> > for(vector<int>::iterator i=mV.begin(); i!=mV.end(); i++) cout
> > <<*i<<" ";
> > cout <<"]\n";
> > }
> >
> > ClassDef(X,1)
> > };
> >
> > #endif
> > fnord
> >
> > Y.h << fnord
> > #ifndef _y_h_
> > #define _y_h_
> >
> > #include "X.h"
> > #include <TObject.h>
> > #include <vector>
> >
> > class Y : public TObject {
> > public:
> > vector<X> mX;
> >
> > void Populate(Int_t M=3) {
> > char a='A', n[2]; for(int i=0; i<M; i++,a++) {
> > sprintf(n,"%c",a);
> > X x(n); x.Populate(i+1);
> > mX.push_back(x);
> > }
> > }
> > void Spit() { for(vector<X>::iterator
> > i=mX.begin(); i!=mX.end(); i++) i->Spit(); }
> > ClassDef(Y,1)
> > };
> >
> > #endif
> > fnord
> >
> > root session 1:
> > root [0] #include <vector>
> > root [1] gSystem->Load("libElDictos.so")
> > (int)0
> > root [2] Y y
> > root [3] y.Populate()
> > root [4] y.Spit()
> > A: [0 ]
> > B: [0 1 ]
> > C: [0 1 2 ]
> > root [5] TFile f("xy.root","RECREATE")
> > root [6] y.Write("Y")
> > (Int_t)134
> > root [7] f.Close()
> > root [8] .q
> >
> > root session 2:
> > root [0] #include <vector>
> > root [1] gSystem->Load("libElDictos.so")
> > (int)0
> > root [2] TFile f("xy.root")
> > root [3] .ls
> > TFile** xy.root
> > TFile* xy.root
> > KEY: Y Y;1
> > root [4] Y.Spit()
> > A: [0 ]
> > B: [0 0 1 ]
> > C: [0 0 1 0 1 2 ]
> >
> > Conclusion:
> > Reading of stl container fails, if its elements contain further stl
> > containers ...
> > eg:
> > // Stream an object of class Y.
> > if (R__b.IsReading()) {
> > Version_t R__v = R__b.ReadVersion(); if (R__v) { }
> > TObject::Streamer(R__b);
> > {
> > int R__i, R__n;
> > X R__t; //!! should be inside loop !!
> > R__b >> R__n;
> > for (R__i = 0; R__i < R__n; R__i++) {
> > R__t.Streamer(R__b);
> > mX.push_back(R__t);
> > }
> > }
> > } else { ...
> >
> > perhaps i live in a dream world, but i would expect the code with
> > declaration inside the loop consume the same number of constructors (due
> > to optimizations for a variable going out of scope copy constructor for
> > stl element is not called). In this case it has to be invoked anyway
> > ... we just gain one destruction (which isn't called if my dream
> > optimization really exists)
> >
> > huh ... back to my histograms ...
> >
> > cheers,
> > matevz
> >
> > --
> > ---------------------------------------------------
> > Matevz Tadel, E-mail: Matevz.Tadel@ijs.si
> > Department of Experimental High Energy Physics F9
> > Jozef Stefan Institute, Jamova 39, P.o.Box 3000
> > SI-1001 Ljubljana, Slovenia
> > Tel.: +386-61-177-3674 Fax: +386-61-125-7074
> > ---------------------------------------------------
> >
> >
--
Org: CERN, European Laboratory for Particle Physics.
Mail: 1211 Geneve 23, Switzerland
E-Mail: Fons.Rademakers@cern.ch Phone: +41 22 7679248
WWW: http://root.cern.ch/~rdm/ Fax: +41 22 7677910
This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:31 MET