Changeset 502 in Sophya


Ignore:
Timestamp:
Oct 23, 1999, 8:52:44 PM (26 years ago)
Author:
ansari
Message:

intro du Realloc cmv 23/10/99

Location:
trunk/SophyaLib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaLib/BaseTools/ndatablock.cc

    r441 r502  
    11// Gestion de block de donnees avec partage de references
    2 //                         C.Magneville          04/99
     2// malheureusement tres mal concu...  C.Magneville 04/99
    33// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
    44#include "machdefs.h"
     
    3737template <class T>
    3838NDataBlock<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()).
    4141: mSz(0), mSRef(NULL), mIsTemp(false)
    4242{
     
    100100void NDataBlock<T>::Alloc(size_t n,T* data,Bridge* br)
    101101// 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)
    103103//    data!=NULL : partage des donnees avec l'adresse data
    104104// Si br==NULL   : les donnees nous appartiennent
     
    106106//
    107107// 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[]"
    109110//    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"
    114119//    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.
    117126// 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//           
    121162{
    122163#ifdef DEBUG_NDATABLOCK
     
    219260
    220261#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;
    223264#endif
    224265
     
    252293if(mSz<n) n = mSz;
    253294memcpy(Data(),data,n*sizeof(T));
     295}
     296
     297template <class T>
     298void 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{
     313if(nnew==0) throw(ParmError("NDataBlock::Realloc  n<=0\n"));
     314
     315// Cas sans re-allocation memoire
     316if(mSRef && nnew<=mSz && ! force) { mSz=nnew; return;}
     317
     318// Cas avec re-allocation memoire
     319size_t ncop;
     320if(!mSRef || mSz==0) ncop=0; else if(mSz<nnew) ncop=mSz; else ncop=nnew;
     321T* dataloc = new T[nnew];
     322if(ncop>0) memcpy(dataloc,mSRef->data,ncop*sizeof(T));
     323if(nnew>ncop) memset(dataloc+ncop,0,(nnew-ncop)*sizeof(T));
     324Alloc(nnew,dataloc,NULL); //Alloc gere partage de reference et bridge
    254325}
    255326
  • trunk/SophyaLib/BaseTools/ndatablock.h

    r489 r502  
    4646  inline void Reset(T v=0)
    4747         {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).
    4853  inline void ReSize(size_t n) {Alloc(n);}
     54
     55  void Realloc(size_t nnew,bool force=false);
    4956 
    5057  // Informations pointeur/data
     
    6067  inline T*        End()          {return mSRef->data+mSz;}
    6168  inline T const*  End() const    {return mSRef->data+mSz;}
     69  inline size_t NRef() const {if(mSRef) return 0; else return mSRef->nref;}
    6270
    6371  // Impression
  • trunk/SophyaLib/NTools/tmatrix.h

    r501 r502  
    4242  inline void ReSize(uint_4 r,uint_4 c)  // Reallocation de place
    4343       {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;}
    4548
    4649  // Informations pointeur/data
  • trunk/SophyaLib/NTools/tvector.h

    r501 r502  
    2323  // Gestion taille/Remplissage
    2424  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);}
    2526
    2627  // Informations pointeur/data
Note: See TracChangeset for help on using the changeset viewer.