MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
mynewmem.h
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/libraries/libmbutil/mynewmem.h,v 1.24 2017/01/12 14:44:05 masarati Exp $ */
2 /*
3  * This library comes with MBDyn (C), a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  *
10  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
11  * via La Masa, 34 - 20156 Milano, Italy
12  * http://www.aero.polimi.it
13  *
14  * Changing this copyright notice is forbidden.
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation (version 2 of the License).
19  *
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29  */
30 
31 /******************************************************************************
32 
33  Allocazione dinamica di memoria controllata con ASSERT e Memory Manager
34 
35 
36  Scritto da
37  Pierangelo Masarati
38  il 05/04/1997
39 
40 
41 Se si usa #define DEBUG sono attivate solo le routines di ASSERT;
42 
43 Se si usa anche #define DEBUG_MEMMANAGER, viene attivato il memory manager.
44 
45 Se si aggiunge #define DEBUG_MEMMANAGER_DELETEBUTKEEPLOG, quando un blocco
46 viene cancellato, ne rimane traccia nel log.
47 
48 Se si aggiunge #define DEBUG_MEMMANAGER_DELETEBUTNOTRELEASE, quando un blocco
49 viene cancellato in realta' la memoria non viene mai rilasciata, solo se ne
50 perde il riferimento
51 
52 
53 E' necessario aggiungere al makefile i seguenti files:
54 
55  <myassert.cc>
56  <mynewmem.cc>
57 
58 Inoltre e' necessario mettere questa intestazione in tutti i files che
59 usano la gestione sicura della memoria:
60 
61  #define DEBUG
62  #define DEBUG_MEMMANAGER
63  [ #define DEBUG_MEMMANAGER_DELETEBUTKEEPLOG ||
64  #define DEBUG_MEMMANAGER_DELETEBUTNOTRELEASE ]
65  #include "mynewmem.h"
66 
67 
68 
69 Le macro di gestione dinamica della memoria sono:
70 
71  SAFENEW(item* pit, item);
72  SAFENEW_(item* pit, item, clMemMan mm);
73  <pit> e' un puntatore al tipo <item> e deve essere <pit> = NULL
74  <item> e' un tipo valido
75  <mm> e' un oggetto della classe clMemMan
76  se #ifdef DEBUG_MEMMANAGER = TRUE,
77  altrimenti non viene usato
78  ###
79  ### ATTENZIONE: QUANDO SI USA LA MACRO "SAFENEW", O <item> E' UN TIPO
80  ### SEMPLICE, IL CUI COSTRUTTORE NON CREA EFFETTI COLLATERALI
81  ### (ALLORA SI PUO' USARE IL COSTRUTTORE AL POSTO DI <item>),
82  ### OPPURE SI DESIDERA UTILIZZARE IL COSTRUTTORE DI DEFAULT.
83  ### SE SI DEVE UTILIZZARE UN COSTRUTTORE COMPLESSO, E' NECESSARIO
84  ### USARE LA MACRO "SAFENEWWITHCONSTRUCTOR"
85  ### (ED E' CONSIGLIABILE USARLA SEMPRE PER TIPI COMPLESSI, ALTRIMENTI
86  ### PUO' ESSERE ESEGUITO PIU' VOLTE IL COSTRUTTORE
87  ###
88 
89  SAFENEWWCONS(item* pit, item, constructor);
90  SAFENEWWITHCONSTRUCTOR_(item* pit, item, constructor, clMemMan mm);
91  <pit> e' un puntatore al tipo <item> e deve essere <pit> = NULL
92  <item> e' un tipo valido
93  <constructor> ' il costruttore di <item>
94  <mm> e' un oggetto della classe clMemMan
95  se #ifdef DEBUG_MEMMANAGER = TRUE,
96  altrimenti non viene usato
97 
98  SAFENEWARR(item* pit, item, type size);
99  SAFENEWARR_(item* pit, item, type size, clMemMan mm);
100  come SAFENEW, solo che viene allocato un array di oggetti
101  di tipo <item> dalle dimensioni determinate da <size>,
102  di tipo indefinito.
103 
104 
105 
106  SAFEDELETE(item* pit);
107  SAFEDELETE_(item* pit, clMemMan mm);
108  come sopra; <pit> deve essere definito e deve essere
109  contenuto in <mm> in qualita' di puntatore all'inizio
110  di un blocco se #ifdef DEBUG_MEMMANAGER = TRUE
111 
112  SAFEDELETEARR(item* pit);
113  SAFEDELETEARR_(item* pit, clMemMan mm);
114  come SAFEDELETE, solo che viene cancellata un'array di oggetti.
115 
116  SAFEDELETEANDFILLARR(item* pit);
117  SAFEDELETEANDFILLARR_(item* pit, clMemMan mm);
118  come SAFEDELETEARR, ma se #ifdef DEBUG_MEMMANAGER = TRUE,
119  prima di deallocare riempe la memoria con il carattere di free;
120  deve essere usato solo quando ogni oggetto dell'array e' stato
121  distrutto con l'apposito distruttore, oppure se gli oggetti
122  non hanno distruttore (verificare come viene distrutto un
123  array di oggetti con distruttore)
124 
125 
126 Uso:
127 
128  item* pit = NULL;
129  clMemMan m;
130 
131  // per allocare:
132  SAFENEW(pit, item, m);
133 
134  if( pit == NULL) // Handle error
135  // L'errore puo' essere gestito in modo migliore attraverso
136  // il casting dell'operatore <new> in modo che non sia
137  // possibile mancare l'allocazione.
138  // In ogni caso la mancata allocazione viene segnalata
139  // su <cerr>.
140 
141  // per deallocare:
142  SAFEDELETE(pit, m);
143 
144  // In modo analogo si usano
145  SAFENEWARR(pit, item, size, m);
146  SAFEDELETEARR(pit, m);
147  SAFEDELETEANDFILLARR(pit, m);
148 
149 
150 Nota: per comportamenti particolari, agire sul codice
151  delle funzioni clMemMan::remove, clMemMan::removeAndFill
152  e delle macro SAFEDELETE(), SAFEDELETEARR()
153  per evitare il delete fisico della memoria o per mantenere un log
154  delle allocazioni avvenute.
155 
156 
157 
158 class clMemMan :
159 
160 La classe clMemMan e' un importante strumento di debugging.
161 Consente di mantenere informazioni relative alla memoria allocata
162 attraverso le macro e quindi di verificare in qualsiasi momento
163 se la memoria utilizzata e' effettivamente disponibile.
164 
165 L'inserimento e la cancellazione dei record avviene automaticamente
166 tramite le macro. L'utente dispone di due strumenti di verifica.
167 Il primo consiste nel dump della struttura della memoria. In esso
168 i records sono ordinati in base al valore del puntatore a cui fanno
169 riferimento. Questo rende possibile una verifica manuale.
170 Il secondo strumento consiste nella possibilita' di marcare
171 i puntatori desiderati con un riferimento qualora siano effettiva-
172 mente disponibili. Quindi un dump dei riferimenti marcati consente
173 di verificare sia la presenza di garbage (memoria non piu' puntata
174 e quindi non referenziabile) che di dangling referencies (puntatori
175 a memoria non piu' disponibile).
176 
177 
178 
179 Le funzioni pubbliche della classe sono:
180 
181 flag clMemMan::fIsBlock(const void* pvBlock, size_t sizeBlock = 1) const;
182  se <pvBlock> e' un puntatore all'inizio di un blocco
183  e <sizeBlock> e' la corretta dimensione del blocco ritorna TRUE,
184  altrimenti FALSE
185 
186 flag clMemMan::fIsPointerToBlock(const void* pvBlock) const;
187  se <pvBlock> e' un puntatore all'inizio di un blocco
188  ritorna TRUE, altrimenti FALSE
189 
190 flag clMemMan::fIsValid(const void* pvValid, size_t sizeValid = 1) const;
191  se <pvValid> e' una valida locazione all'interno di un blocco e
192  <(void*)pvalid+sizeValid-1> non eccede il blocco ritorna TRUE,
193  altrimenti FALSE
194 
195 size_t clMemMan::sizeOfBlock(const void* pvSizeOf) const;
196  se <pvSizeOf> e' un puntatore all'inizio di un blocco,
197  ne ritorna la dimensione
198 
199 flag clMemMan::fIsArray(const void* pvIsArray) const;
200  se <pvIsArray> e' un puntatore all'inizio di un blocco,
201  ritorna TRUE se e' un'array, altrimenti FALSE
202 
203 eStatus clMemMan::eBlockStatus(const void* pvBStatus) const;
204  se <pvIsArray> e' un puntatore all'inizio di un blocco,
205  ne ritorna lo stato con un valore appartenente all'enum <eStatus>
206 
207 void clMemMan::ClearRefs(void);
208  azzera i flag di riferimento a tutti i puntatori
209 
210 void clMemMan::PutRef(const void* pvRef);
211  se <pvRef> e' un puntatore all'inizio di un blocco,
212  ne setta il riferimento
213 
214 flag clMemMan::fIsRefd(const void* pvIsRefd) const;
215  se <pvRef> e' un puntatore all'inizio di un blocco,
216  ritorna TRUE se il riferimento e' settato
217 
218 void clMemMan::DumpRef(ostream& rout) const;
219  invia la stampa dei blocchi suddivisi in base ai riferimenti
220  ad un ostream
221 
222 ostream& operator << (ostream& rout, const clMemMan& rm);
223  invia la stampa dei blocchi con le relative proprieta' ad un ostream
224 
225 
226 Esempio completo:
227 
228  // ...
229 
230  #define DEBUG
231  #define DEBUG_MEMMANAGER
232  #include "mynewmem.h"
233 
234  // ...
235 
236  // Uso dei riferimenti:
237 
238  #ifdef DEBUG_MEMMANAGER
239  clMemMan m("Test"); // Memory Manager
240  #endif
241 
242  void* pb = NULL;
243  SAFENEW(pb, char, m); // Allocazione di un byte
244 
245  #ifdef DEBUG_MEMMANAGER
246  m.ClearRefs(); // Pulisce i Ref
247  m.PutRef(pb); // Setta il Ref di pb
248  if (m.fIsRefd(pb)) { // Ritorna TRUE
249  m.DumpRef(cout); // scrive i dati
250  }
251  #endif
252 
253  SAFEDELETE(pb, m); // Deallocazione
254  if (pb) { // Ritorna FALSE, perche' SAFEDELETE
255  NULL; // pone comunque pb = NULL
256  }
257 
258  // Uso delle utilities:
259 
260  SAFENEWARR(pb, char, 10, m); // Allocazione di 10 bytes
261 
262  #ifdef DEBUG_MEMMANAGER
263  if (m.fIsPointerToBlock(pb), 10) { // Ritorna TRUE
264  size_t size = m.sizeOfBlock(pb);// Dim. del blocco
265  int iItems = 1;
266  if (m.fIsArray(pb)) { // Se array calcola le dim.
267  iItems = size/sizeof(*pb);
268  cout << "\nNumero di elementi: "
269  << iItems << endl;
270  }
271  void* pbTmp = pb;
272  while (size--) { // Azzera la memoria
273  // (operazione da non fare
274  *pbTmp++ = '\0';// se devono essere eseguiti
275  // i distruttori
276  }
277  }
278  #endif
279  SAFEDELETEARR(pb, m); // Libera la memoria
280 
281 
282 Si noti come, togliendo #define DEBUG_MEMMANAGER, si abbia il codice
283 di debug semplificato, con gli ASSERT ed altri controlli, mentre,
284 togliendo anche #define DEBUG, si abbia in modo autometico il codice
285 in versione release, senza alcun overhead
286 
287 ******************************************************************************/
288 
289 #ifndef MYNEWMEM_H
290 #define MYNEWMEM_H
291 
292 
293 #include <myassert.h>
294 #include <except.h>
295 
296 #ifdef DEBUG
297 
298 /* Dichiarazione di funzioni usate nella versione debug */
299 extern void _Safenew(const char* file, int line, int flag = 0);
300 extern void _Safenewfill(void* pv, size_t size, char fill);
301 
302 const char cDebugAlloc = 'A';
303 const char cDebugFree = 'F';
304 
305 #ifdef DEBUG_MEMMANAGER
306 
307 /* Dichiarazione delle macro di debug con memory manager */
308 #define SAFENEW_(pnt, item, memman) \
309  do { \
310  ASSERT(!(pnt)); \
311  ASSERT(sizeof(item)); \
312  (pnt) = new item; \
313  if (!(pnt)) { \
314  _Safenew(__FILE__, __LINE__); \
315  } \
316  (memman).add((void*)(pnt), sizeof(item)); \
317  } while(0)
318 
319 /* Dichiarazione delle macro di debug con memory manager */
320 #define SAFENEWWITHCONSTRUCTOR_(pnt, item, constructor, memman) \
321  do { \
322  ASSERT(!(pnt)); \
323  ASSERT(sizeof(item)); \
324  (pnt) = new constructor; \
325  if (!(pnt)) { \
326  _Safenew(__FILE__, __LINE__); \
327  } \
328  (memman).add((void*)(pnt), sizeof(item)); \
329  } while (0)
330 
331 /* Attenzione: questa operazione e' lecita solo se
332  * non e' stato eseguito un costruttore
333  * _Safenewfill(pnt, sizeof(item), cDebugAlloc); */
334 #define SAFENEWARR_(pnt, item, sz, memman) \
335  do { \
336  ASSERT(!(pnt)); \
337  ASSERT(sizeof(item)); \
338  ASSERT(sz); \
339  (pnt) = new item[sz]; \
340  if (!(pnt)) { \
341  _Safenew(__FILE__, __LINE__, 1); \
342  } \
343  (memman).add((void*)(pnt), sizeof(item)*(sz), 1); \
344  _Safenewfill((void*)pnt, sizeof(item)*(sz), cDebugAlloc); \
345  } while (0)
346 
347 /* questa e' sicura anche se e' stato eseguito un costruttore */
348 #define SAFENEWARRNOFILL_(pnt, item, sz, memman) \
349  do { \
350  ASSERT(!(pnt)); \
351  ASSERT(sizeof(item)); \
352  ASSERT(sz); \
353  (pnt) = new item[sz]; \
354  if (!(pnt)) { \
355  _Safenew(__FILE__, __LINE__, 1); \
356  } \
357  (memman).add((void*)(pnt), sizeof(item)*(sz), 1); \
358  } while (0)
359 
360 #define SAFESTRDUP_(pnt, src, memman) \
361  do { \
362  ASSERT(!(pnt)); \
363  ASSERT((src)); \
364  unsigned int l = strlen((src))+1; \
365  (pnt) = new char[l]; \
366  if ( !(pnt) ) { \
367  _Safenew(__FILE__, __LINE__, 1); \
368  } \
369  strcpy((char *)(pnt), (src)); \
370  (memman).add((void*)(pnt), l, 1); \
371  } while (0)
372 
373 /* Qui il fill e' lecito perche' per le arrays
374  * non sono eseguiti i costruttori */
375 
376 #ifndef DEBUG_MEMMANAGER_DELETEBUTKEEPLOG
377 
378 #ifndef DEBUG_MEMMANAGER_DELETEBUTNOTRELEASE
379 
380 #define SAFEDELETE_(pnt, memman) \
381  do { \
382  ASSERT(pnt); \
383  (memman).remove((void*)(pnt)); \
384  delete (pnt); \
385  (pnt) = NULL; \
386  } while (0)
387 
388 #define SAFEDELETEARR_(pnt, memman) \
389  do { \
390  ASSERT(pnt); \
391  (memman).remove((void*)(pnt), 1); \
392  delete[] (pnt); \
393  (pnt) = NULL; \
394  } while (0)
395 
396 #define SAFEDELETEANDFILLARR_(pnt, memman) \
397  do { \
398  ASSERT(pnt); \
399  (memman).remove((void*)(pnt), 1, 1); \
400  delete[] (pnt); \
401  (pnt) = NULL; \
402  } while (0)
403 
404 #endif /* !DEBUG_MEMMANAGER_DELETEBUTNOTRELEASE */
405 
406 #endif /* !DEBUG_MEMMANAGER_DELETEBUTKEEPLOG */
407 
408 #ifdef DEBUG_MEMMANAGER_DELETEBUTKEEPLOG
409 
410 #define SAFEDELETE_(pnt, memman) \
411  do { \
412  ASSERT(pnt); \
413  (memman).removeButKeepLog((void*)(pnt)); \
414  delete (pnt); \
415  (pnt) = NULL; \
416  } while (0)
417 
418 #define SAFEDELETEARR_(pnt, memman) \
419  do { \
420  ASSERT(pnt); \
421  (memman).removeButKeepLog((void*)(pnt), 1); \
422  delete[] (pnt); \
423  (pnt) = NULL; \
424  } while (0)
425 
426 #define SAFEDELETEANDFILLARR_(pnt, memman) \
427  do { \
428  ASSERT(pnt); \
429  (memman).removeButKeepLog((void*)(pnt), 1); \
430  delete[] (pnt); \
431  (pnt) = NULL; \
432  } while (0)
433 
434 #endif /* DEBUG_MEMMANAGER_DELETEBUTKEEPLOG */
435 
436 #ifdef DEBUG_MEMMANAGER_DELETEBUTNOTRELEASE
437 
438 #define SAFEDELETE_(pnt, memman) \
439  do { \
440  ASSERT(pnt); \
441  (memman).removeButNotRelease((void*)(pnt)); \
442  delete (pnt); \
443  (pnt) = NULL; \
444  } while (0)
445 
446 #define SAFEDELETEARR_(pnt, memman) \
447  do { \
448  ASSERT(pnt); \
449  (memman).removeButNotRelease((void*)(pnt), 1); \
450  delete[] (pnt); \
451  (pnt) = NULL; \
452  } while (0)
453 
454 #define SAFEDELETEANDFILLARR_(pnt, memman) \
455  do { \
456  ASSERT(pnt); \
457  (memman).removeButNotRelease((void*)(pnt), 1); \
458  delete[] (pnt); \
459  (pnt) = NULL; \
460  } while (0)
461 
462 #endif /* DEBUG_MEMMANAGER_DELETEBUTNOTRELEASE */
463 
464 /* enum degli stati della memoria */
465 enum eStatus {
466  UNKNOWN,
467  ALLOCATED,
468  FREED,
469  FREEDBUTNOTRELEASED
470 };
471 
472 /* struttura dei dati di un blocco di memoria */
473 struct stMemBlock {
474  void* pv;
475  size_t size;
476  eStatus eSt;
477  flag fArr;
478  flag fRef;
479 
480  stMemBlock(void* _pv = NULL, size_t _size = 0, eStatus _eSt = UNKNOWN,
481  flag _fArr = 0, flag _fRef = 0)
482  : pv(_pv), size(_size), eSt(_eSt), fArr(_fArr), fRef(_fRef) {
483  NO_OP;
484  };
485 };
486 
487 /* classe del memory manager */
488 class clMemMan {
489  friend ostream& operator << (ostream& rout, const clMemMan& rm);
490 
491 public:
492  class ErrGeneric : public MBDynErrBase {
493  public:
495  };
496  class ErrNotFound : public MBDynErrBase {
497  public:
499  };
500 
501 private:
502  struct stList {
503  stMemBlock stMB;
504  stList* pstNext;
505  stList(stMemBlock stIn) : stMB(stIn), pstNext(NULL) {
506  NO_OP;
507  };
508  };
509 
510  stList* pstRoot;
511  char* sName;
512 
513  stList* pstFindElem(const void* pvToFind) const;
514  stList* pstFindPrev(const void* pvToFindPrev) const;
515 
516  enum eRemoveMode {
517  RELEASE,
518  DELBUTKEEPLOG,
519  DELBUTNOTRELEASE
520  };
521 
522  void _remove(const void* pvToRemove, eRemoveMode eMode, flag fArr,
523  flag fFill);
524 
525 public:
526  clMemMan(char* sName = NULL);
527  ~clMemMan(void);
528 
529  flag fIsBlock(const void* pvBlock, size_t sizeBlock = 1) const;
530  flag fIsPointerToBlock(const void* pvBlock) const;
531  flag fIsValid(const void* pvValid, size_t sizeValid = 1) const;
532  size_t sizeOfBlock(const void* pvSizeOf) const;
533  flag fIsArray(const void* pvIsArray) const;
534  eStatus eBlockStatus(const void* pvBStatus) const;
535 
536  void ClearRefs(void);
537  void PutRef(const void* pvRef);
538  flag fIsRefd(const void* pvIsRefd) const;
539  ostream& DumpRef(ostream& rout) const;
540 
541  void add(const void* pvIn, size_t sizeIn, flag fArr = 0);
542  inline void remove(const void* pvToRemove, flag fArr = 0, flag fFill = 0) {
543  _remove(pvToRemove, RELEASE, fArr, fFill);
544  };
545 
546  inline void removeButNotRelease(const void* pvToRemove, flag fArr = 0, flag fFill = 0) {
547  _remove(pvToRemove, DELBUTNOTRELEASE, fArr, fFill);
548  };
549 
550  inline void removeButKeepLog(const void* pvToRemove, flag fArr = 0, flag fFill = 0) {
551  _remove(pvToRemove, DELBUTKEEPLOG, fArr, fFill);
552  };
553 };
554 
555 extern clMemMan defaultMemoryManager;
556 
557 /* funzione di stream del memory manager */
558 extern ostream& operator << (ostream& rout, const clMemMan& rm);
559 
560 #else /* !DEBUG_MEMMANAGER */
561 
562 /* dichiarazione delle macro di debug senza memory manager */
563 #define SAFENEW_(pnt, item, memman) \
564  do { \
565  ASSERT(!(pnt)); \
566  ASSERT(sizeof(item)); \
567  (pnt) = new item; \
568  if (!(pnt)) { \
569  _Safenew(__FILE__, __LINE__); \
570  } \
571  } while (0)
572 
573 /* Dichiarazione delle macro di debug senza memory manager */
574 #define SAFENEWWITHCONSTRUCTOR_(pnt, item, constructor, memman) \
575  do { \
576  ASSERT(!(pnt)); \
577  ASSERT(sizeof(item)); \
578  (pnt) = new constructor; \
579  if (!(pnt)) { \
580  _Safenew(__FILE__, __LINE__); \
581  } \
582  } while (0)
583 
584 /* Attenzione: questa operazione e' lecita solo se
585  * non e' stato eseguito un costruttore
586  * _Safenewfill(pnt, sizeof(item), cDebugAlloc) */
587 
588 #define SAFENEWARR_(pnt, item, sz, memman) \
589  do { \
590  ASSERT(!(pnt)); \
591  ASSERT(sizeof(item)); \
592  ASSERT(sz); \
593  (pnt) = new item[sz]; \
594  if (!(pnt)) { \
595  _Safenew(__FILE__, __LINE__, 1); \
596  } \
597  _Safenewfill(pnt, sizeof(item)*(sz), cDebugAlloc); \
598  } while (0)
599 
600 /* questa e' sicura anche se e' stato eseguito un costruttore */
601 #define SAFENEWARRNOFILL_(pnt, item, sz, memman) \
602  do { \
603  ASSERT(!(pnt)); \
604  ASSERT(sizeof(item)); \
605  ASSERT(sz); \
606  (pnt) = new item[sz]; \
607  if (!(pnt)) { \
608  _Safenew(__FILE__, __LINE__, 1); \
609  } \
610  } while (0)
611 
612 #define SAFESTRDUP_(pnt, src, memman) \
613  do { \
614  ASSERT(!(pnt)); \
615  ASSERT((src)); \
616  unsigned int l = strlen((src))+1; \
617  (pnt) = new char[l]; \
618  if (!(pnt)) { \
619  _Safenew(__FILE__, __LINE__, 1); \
620  } \
621  strcpy((char *)(pnt), (src)); \
622  } while (0)
623 
624 /* Qui il fill e' lecito perche' per le arrays
625  * non sono eseguiti i costruttori */
626 
627 #define SAFEDELETE_(pnt, memman) \
628  do { \
629  ASSERT((pnt) != 0); \
630  delete (pnt); \
631  (pnt) = NULL; \
632  } while (0)
633 
634 #define SAFEDELETEARR_(pnt, memman) \
635  do { \
636  ASSERT((pnt) != 0); \
637  delete[] (pnt); \
638  (pnt) = NULL; \
639  } while (0)
640 
641 #define SAFEDELETEANDFILLARR_(pnt, memman) \
642  do { \
643  ASSERT((pnt) != 0); \
644  delete[] (pnt); \
645  (pnt) = NULL; \
646  } while (0)
647 
648 #endif /* !DEBUG_MEMMANAGER */
649 
650 #else /* !DEBUG */
651 
652 /* dichiarazione delle macro nella versione da release */
653 #define SAFENEW_(pnt, item, memman) \
654  (pnt) = new item
655 
656 /* dichiarazione delle macro nella versione da release */
657 #define SAFENEWWITHCONSTRUCTOR_(pnt, item, constructor, memman) \
658  (pnt) = new constructor
659 
660 #define SAFENEWARR_(pnt, item, sz, memman) \
661  (pnt) = new item[sz]
662 
663 #define SAFENEWARRNOFILL_(pnt, item, sz, memman) \
664  (pnt) = new item[sz]
665 
666 #define SAFESTRDUP_(pnt, src, memman) \
667  do { \
668  unsigned int l = strlen((src))+1; \
669  (pnt) = new char[l]; \
670  strcpy((char *)(pnt), (src)); \
671  } while (0)
672 
673 #define SAFEDELETE_(pnt, memman) \
674  do { \
675  delete (pnt); \
676  (pnt) = NULL; \
677  } while (0)
678 
679 #define SAFEDELETEARR_(pnt, memman) \
680  do { \
681  delete[] (pnt); \
682  (pnt) = NULL; \
683  } while (0)
684 
685 #define SAFEDELETEANDFILLARR_(pnt, memman) \
686  do { \
687  delete[] (pnt); \
688  (pnt) = NULL; \
689  } while (0)
690 
691 #define defaultMemoryManager 0
692 
693 #endif /* !DEBUG */
694 
695 #define SAFENEW(pnt, item) \
696  SAFENEW_(pnt, item, defaultMemoryManager)
697 
698 #define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor) \
699  SAFENEWWITHCONSTRUCTOR_(pnt, item, constructor, defaultMemoryManager)
700 
701 #define SAFENEWARR(pnt, item, sz) \
702  SAFENEWARR_(pnt, item, sz, defaultMemoryManager)
703 
704 #define SAFENEWARRNOFILL(pnt, item, sz) \
705  SAFENEWARRNOFILL_(pnt, item, sz, defaultMemoryManager)
706 
707 #define SAFESTRDUP(pnt, src) \
708  SAFESTRDUP_(pnt, src, defaultMemoryManager)
709 
710 #define SAFEDELETE(pnt) \
711  SAFEDELETE_(pnt, defaultMemoryManager)
712 
713 #define SAFEDELETEARR(pnt) \
714  SAFEDELETEARR_(pnt, defaultMemoryManager)
715 
716 #define SAFEDELETEANDFILLARR(pnt) \
717  SAFEDELETEANDFILLARR_(pnt, defaultMemoryManager)
718 
719 #endif /* MYNEWMEM_H */
720 
long int flag
Definition: mbdyn.h:43
#define MBDYN_EXCEPT_ARGS_PASSTHRU
Definition: except.h:55
#define MBDYN_EXCEPT_ARGS_DECL
Definition: except.h:43
#define NO_OP
Definition: myassert.h:74
std::ostream & operator<<(std::ostream &out, const FullMatrixHandler &m)
Definition: fullmh.cc:352
static char * file
Definition: ann_in.c:101
#define defaultMemoryManager
Definition: mynewmem.h:691