- Timestamp:
- Oct 23, 1999, 8:52:44 PM (26 years ago)
- Location:
- trunk/SophyaLib
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaLib/BaseTools/ndatablock.cc
r441 r502 1 1 // Gestion de block de donnees avec partage de references 2 // C.Magneville04/992 // malheureusement tres mal concu... C.Magneville 04/99 3 3 // LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA 4 4 #include "machdefs.h" … … 37 37 template <class T> 38 38 NDataBlock<T>::NDataBlock(size_t n, T* data, Bridge* br) 39 // Createur d'une structure de "n" donnees, avec donnees preallouees 40 // (Voir explications dans Alloc())39 // Createur d'une structure de "n" donnees, avec donnees preallouees. 40 // Attention createur TRES DANGEREUX (Voir explications dans Alloc()). 41 41 : mSz(0), mSRef(NULL), mIsTemp(false) 42 42 { … … 100 100 void NDataBlock<T>::Alloc(size_t n,T* data,Bridge* br) 101 101 // Allocation d'un NOUVEL espace de stoquage de "n" donnees 102 // Si data==NULL : allocation de l'espace memoire ( vide)102 // Si data==NULL : allocation de l'espace memoire (remplit de zeros) 103 103 // data!=NULL : partage des donnees avec l'adresse data 104 104 // Si br==NULL : les donnees nous appartiennent … … 106 106 // 107 107 // Exemple: on veut connecter a un tableau de T* 108 // 1- On veut que NDataBlock NE DESALLOUE PAS le tableau "data" 108 // > float *x = new float[5]; ... remplissage de x[] ...; 109 // 1- On veut que NDataBlock NE DESALLOUE PAS le tableau "x[]" 109 110 // a- Premiere solution 110 // float *x = new float[5]; ... remplissage de x[] ...; 111 // NDataBlock A(5,x,new Bridge); 112 // delete [] x; // Il faut deleter explicitement 113 // (et Bridge est delete par le destructeur de la classe) 111 // > NDataBlock A(5,x,new Bridge); 112 // ...... 113 // > delete [] x; 114 // - Il faut deleter x[] explicitement. 115 // - Le destructeur de "A" ne detruit pas x[]. 116 // ATTENTION: Une fois x[] detruit, "A" ne peut 117 // plus acceder les donnees! 118 // - Bridge est detruit par le destructeur de "A" 114 119 // b- Autre solution: 115 // NDataBlock A(5); A.FillFrom(5,x); 116 // delete [] x; // Il faut deleter explicitement 120 // > NDataBlock A(5); A.FillFrom(5,x); 121 // > delete [] x; 122 // ...... 123 // - Il faut deleter x[] explicitement. 124 // - "A" possede une copie en local de x[]. 125 // - Le destructeur de "A" ne detruit pas x[] mais la copie locale. 117 126 // 2- On veut que NDataBlock desalloue le tableau 118 // float *x = new float[5]; ... remplissage de x[] ...; 119 // NDataBlock A(5,x); 120 // (Ne Pas Faire "delete [] x;") 127 // > NDataBlock A(5,x); 128 // - Ne Pas Faire "delete [] x;" 129 // - "A" partage les donnees avec x[]. 130 // - Le destructeur de "A" detruit x[]. 131 // 132 // --- REMARQUE SUR LE DANGER DE CERTAINES SITUATIONS (CMV): 133 // 1-/ x = new float[n1]; NDataBlock A(n2,x); 134 // 1er danger: si n2>n1 depassement de tableaux (core dump) 135 // 2sd danger: celui qui alloue x[] ne doit pas faire le "delete" 136 // en desaccord avec toutes les regles de bonne conduite. 137 // 2-/ float x[5]={1,2,3,4,5}; {NDataBlock A(n2,&x[0]);} cout<<x[2]; 138 // Ici, a la sortie du bloc {}, le destructeur de "A" va detruire 139 // l'adresse de &x[0]: je n'ose imaginer que ca se fasse sans probleme 140 // et de toute facon, cout<<x[2]; va surement faire des etincelles. 141 // 3-/ x = new float[n1]; NDataBlock A(n2,x,new Bridge); 142 // 1er danger: si n2>n1 depassement de tableaux (core dump) 143 // 2sd danger: si la methode bridgee (blitz?) detruit x[] 144 // "A" n'a plus de donnees connectees! 145 // --- CONCLUSION 146 // Cette classe est franchement merdique. 147 // - On peut accepter la prise de risque liee a NDataBlock(n2,x,new Bridge); 148 // car je ne vois pas comment on pourrait faire autrement pour connecter 149 // un tableau de type blitz par exemple. 150 // - Par contre le createur NDataBlock(n2,x); doit etre interdit 151 // dans sa forme actelle car trop dangereux et il me semble inutile. 152 // - Dans cette nouvelle optique: 153 // NDataBlock(n2,x,new Bridge) et NDataBlock(n2,x) disparaissent 154 // On remplace par NDataBlock(n2,x) {Alloc(n2,x,new Bridge);} 155 // qui force le Bridge dans tout les cas puisque NDataBlock 156 // ne possede pas les donnees. 157 // Mais puis-je encore le faire vu que NDataBlock est a la base 158 // de TVector,TMatrix et qu'il faut donc reprendre tout le code DPC 159 // - Quoiqu'il arrive Alloc est une methode privee et peut donc rester 160 // sous sa forme actuelle. 161 // 121 162 { 122 163 #ifdef DEBUG_NDATABLOCK … … 219 260 220 261 #ifdef DEBUG_NDATABLOCK 221 cout<<"...?_NDataBlock::Delete() pas de desallocation il reste nref="222 <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;262 cout<<"...?_NDataBlock::Delete() pas de desallocation il reste nref=" 263 <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl; 223 264 #endif 224 265 … … 252 293 if(mSz<n) n = mSz; 253 294 memcpy(Data(),data,n*sizeof(T)); 295 } 296 297 template <class T> 298 void NDataBlock<T>::Realloc(size_t nnew,bool force) 299 // Re-allocation de "nnew" place memoire pour les donnees 300 // avec conservation des "nold" donnees precedentes si possible. 301 // "force" gere la re-allocation de la place memoire pour les donnees. 302 // Divers cas se presentent: 303 // a-/ *** nnew>nold force=quelconque *** 304 // place re-allouee, donnees [0,nold[ copiees, surplus [nold,new[ mis a zero 305 // b-/ *** nnew<=nold force=true *** 306 // place re-allouee, donnees [0,nnew[ copiees, pas de surplus 307 // c-/ *** nnew<=nold force=false *** 308 // place non re-allouee, seule la valeur de la taille est diminuee 309 // - On tient compte du partage des donnees dans tous les cas. 310 // - Si il n'y a pas de donnees connectees a la classe, on re-alloue 311 // dans tous les cas 312 { 313 if(nnew==0) throw(ParmError("NDataBlock::Realloc n<=0\n")); 314 315 // Cas sans re-allocation memoire 316 if(mSRef && nnew<=mSz && ! force) { mSz=nnew; return;} 317 318 // Cas avec re-allocation memoire 319 size_t ncop; 320 if(!mSRef || mSz==0) ncop=0; else if(mSz<nnew) ncop=mSz; else ncop=nnew; 321 T* dataloc = new T[nnew]; 322 if(ncop>0) memcpy(dataloc,mSRef->data,ncop*sizeof(T)); 323 if(nnew>ncop) memset(dataloc+ncop,0,(nnew-ncop)*sizeof(T)); 324 Alloc(nnew,dataloc,NULL); //Alloc gere partage de reference et bridge 254 325 } 255 326 -
trunk/SophyaLib/BaseTools/ndatablock.h
r489 r502 46 46 inline void Reset(T v=0) 47 47 {if(mSz==0) return; T *p=Begin(),*pe=End(); while(p<pe) *p++=v;} 48 49 // ReSize redimmensionne une structure pour "n" donnees. 50 // Les donnees precedentes sont perdues (pour cette classe) 51 // et le nouveau tableau mis a zero. La nouvelle structure de 52 // donnees n'a qu'une reference (celle de cette classe). 48 53 inline void ReSize(size_t n) {Alloc(n);} 54 55 void Realloc(size_t nnew,bool force=false); 49 56 50 57 // Informations pointeur/data … … 60 67 inline T* End() {return mSRef->data+mSz;} 61 68 inline T const* End() const {return mSRef->data+mSz;} 69 inline size_t NRef() const {if(mSRef) return 0; else return mSRef->nref;} 62 70 63 71 // Impression -
trunk/SophyaLib/NTools/tmatrix.h
r501 r502 42 42 inline void ReSize(uint_4 r,uint_4 c) // Reallocation de place 43 43 {if(r==0||c==0) throw(SzMismatchError("TMatrix::ReSize r ou c==0\n")); 44 mNr = r; mNc = c; mNDBlock.ReSize(r*c);} 44 mNDBlock.ReSize(r*c); mNr = r; mNc = c;} 45 inline void Realloc(uint_4 r,uint_4 c,bool force=false) 46 {if(r==0||c==0) throw(SzMismatchError("TMatrix::Realloc r ou c==0\n")); 47 mNDBlock.Realloc(r*c,force); mNr = r; mNc = c;} 45 48 46 49 // Informations pointeur/data -
trunk/SophyaLib/NTools/tvector.h
r501 r502 23 23 // Gestion taille/Remplissage 24 24 inline void ReSize(uint_4 n) {TMatrix<T>::ReSize(n,1);} // Reallocation de place 25 inline void Realloc(uint_4 n,bool force=false) {TMatrix<T>::Realloc(n,1,force);} 25 26 26 27 // Informations pointeur/data
Note:
See TracChangeset
for help on using the changeset viewer.