Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

mcw_malloc.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 #include "mcw_malloc.h"
00008 #include "Amalloc.h"
00009 /*--------------------------------------------------------------------------
00010   24 Jan 2001: Modified heavily to use a hash table instead of a linear
00011                array to store the data about each allocated block.
00012   16 Feb 2001: Modified to include some debug traceback info (if
00013                USE_TRACING is defined - searce for TRAC to see code).
00014   -- RWCox
00015 ----------------------------------------------------------------------------*/
00016 
00017 #define MAGIC  ((char) 0xd7)
00018 #define NEXTRA (2*sizeof(int))
00019 
00020 #undef malloc
00021 #undef realloc
00022 #undef calloc
00023 #undef free
00024 #undef XtMalloc
00025 #undef XtRealloc
00026 #undef XtFree
00027 #undef XtCalloc
00028 #undef mcw_malloc
00029 #undef mcw_realloc
00030 #undef mcw_calloc
00031 #undef mcw_free
00032 
00033 #undef  UINT
00034 #define UINT unsigned int
00035 
00036 #ifdef USE_TRACING        /* 16 Feb 2001 */
00037 # include "debugtrace.h"
00038 # undef  NTB    /* number of traceback levels to keep for each malloc() */
00039 # define NTB 5  /* (chosen to make sizeof(mallitem) a multiple of 8)    */
00040 #endif
00041 
00042 /*-- struct to hold info about each malloc()-ed block --*/
00043 
00044 typedef struct {
00045    void * pmt ;   /* pointer to actually malloc-ed block */
00046    size_t psz ;   /* size of allocated block */
00047    char * pfn ;   /* function name that called */
00048    int    pln ;   /* function line number */
00049    UINT   pss ;   /* serial number of this malloc */
00050 #ifdef USE_TRACING
00051    char * ptb[NTB] ; /* traceback from debugtrace.h */
00052 #endif
00053 } mallitem ;
00054 
00055 /** set hash table size (to a prime number, please) **/
00056 
00057 /** #define SLOTS 503   **/ /* a little small */
00058 
00059 #define SLOTS 8191
00060 
00061 /** #define SLOTS 16381 **/
00062 /** #define SLOTS 32003 **/
00063 
00064 static mallitem ** htab  = NULL ; /* table of lists */
00065 static int *       nhtab = NULL ; /* size of each list */
00066 static UINT       serial = 0    ; /* serial number of allocation */
00067 
00068 #undef INLINE
00069 #ifdef __GNUC__
00070 # define INLINE inline
00071 #else
00072 # define INLINE /*nada*/
00073 #endif
00074 
00075 #ifdef USE_TRACING
00076 # define ADD_TRACEBACK(ip)                                                   \
00077    do{ int tt ;                                                              \
00078        for( tt=1 ; tt <= NTB ; tt++ )                                        \
00079          ip->ptb[tt-1] = (tt < DBG_num) ? DBG_rout[DBG_num-tt] : NULL; } while(0)
00080 #else
00081 # define ADD_TRACEBACK(ip) /* nada */
00082 #endif
00083 
00084 /*---------------------------------------------------------------
00085   Compute a unique non-negative integer key from an address
00086 -----------------------------------------------------------------*/
00087 
00088 static INLINE UINT mallkey( char * fred )
00089 {
00090    UINT q = ((UINT) fred) ;
00091 
00092    q =   ((q & 0xf0f0f0f0) >> 4)   /* swap nibbles */
00093        | ((q & 0x0f0f0f0f) << 4) ;
00094 
00095    return q ;
00096 }
00097 
00098 /*----------------------------------------------------------------
00099    Find an address in the hash table;
00100    returns a pointer to the mallitem that owns it (or NULL)
00101 ------------------------------------------------------------------*/
00102 
00103 static mallitem * ptr_tracker( void * fred )
00104 {
00105    int jj,kk ;
00106 
00107    if( fred == NULL ) return NULL ;
00108 
00109    jj = mallkey((char *)fred) % SLOTS ;      /* hash table location */
00110 
00111    if( htab[jj] == NULL ) return NULL ;  /* nothing there */
00112 
00113    for( kk=0 ; kk < nhtab[jj] ; kk++ )   /* scan for match */
00114       if( htab[jj][kk].pmt == fred ) return (htab[jj]+kk) ;
00115 
00116    return NULL ; /* no match found */
00117 }
00118 
00119 /*-----------------------------------------------------------------*/
00120 /*-- this macro finds an address from the user in the hash table --*/
00121 
00122 #define shift_tracker(fff)  ptr_tracker( ((char *)(fff)) - NEXTRA )
00123 
00124 /*-----------------------------------------------------------------
00125    Find an empty entry in the hash table list [jj] and return
00126    a pointer to it.  Will create the entry, if need be.
00127 -------------------------------------------------------------------*/
00128 
00129 static mallitem * find_empty_slot( int jj )
00130 {
00131    int kk ;
00132 
00133    if( htab[jj] == NULL ){                               /* must make new list  */
00134       htab[jj] = (mallitem *) malloc(sizeof(mallitem)) ; /* of length 1 at [jj] */
00135      nhtab[jj] = 1 ;
00136       kk       = 0 ;
00137       htab[jj][0].pmt = NULL ;  /* mark as empty */
00138    } else {
00139       for( kk=nhtab[jj]-1 ; kk >= 0 ; kk-- )    /* scan (backwards) for NULL entry */
00140          if( htab[jj][kk].pmt == NULL ) break ; /* found it? */
00141 
00142       if( kk < 0 ){                             /* must make list longer */
00143          kk = nhtab[jj] ; nhtab[jj]++ ;
00144          htab[jj] = (mallitem *) realloc( htab[jj], sizeof(mallitem)*nhtab[jj] ) ;
00145          htab[jj][kk].pmt = NULL ;  /* mark as empty */
00146       }
00147    }
00148 
00149    return (htab[jj]+kk) ;
00150 }
00151 
00152 /*----------------------------------------------------------------
00153    Add an entry to the hash table, given the
00154    address, the user's size, and the filename and line number.
00155 ------------------------------------------------------------------*/
00156 
00157 static void add_tracker( void * fred , size_t n , char * fn , int ln )
00158 {
00159    int jj ;
00160    mallitem * ip ;
00161 
00162    if( fred == NULL ) return ;   /* bad news */
00163 
00164    jj = mallkey((char *)fred) % SLOTS ;  /* which hash list to use */
00165    ip = find_empty_slot(jj) ;    /* get an empty slot in this list */
00166 
00167    /* now put the data into the hash table */
00168 
00169    ip->pmt = fred ;
00170    ip->psz = n ;
00171    ip->pfn = fn ;
00172    ip->pln = ln ;
00173    ip->pss = ++serial ;
00174 
00175    ADD_TRACEBACK(ip) ;  /* 16 Feb 2001 */
00176 
00177    return ;
00178 }
00179 
00180 /*-----------------------------------------------------------------
00181   The tracking replacement for malloc
00182 -------------------------------------------------------------------*/
00183 
00184 static void * malloc_track( size_t n , char * fn , int ln )
00185 {
00186    char * fred ;
00187    size_t nn = n + 2*NEXTRA ;
00188    int ii ;
00189 
00190    fred = (char *) malloc(nn) ;
00191    if( fred == NULL ){                                     /* real bad news */
00192       fprintf(stderr,
00193               "\n*** MCW_malloc(%d) from %s#%d FAILS!\a\n",  /* 02 Jan 2002 */
00194               (int)n , fn , ln ) ;
00195       return NULL ;
00196    }
00197 
00198    /* mark overrun buffers */
00199 
00200    for( ii=0 ; ii < NEXTRA ; ii++ )
00201       fred[ii] = fred[n+NEXTRA+ii] = MAGIC ;
00202 
00203    add_tracker(fred,n,fn,ln) ;      /* put in hash table */
00204    return (void *)(fred+NEXTRA) ;
00205 }
00206 
00207 /*-----------------------------------------------------------------
00208   Check an entry in the hash table for local overrun integrity
00209 -------------------------------------------------------------------*/
00210 
00211 static const char *pr_nam = NULL ;
00212 static       int   pr_lin = 0 ;
00213 
00214 static void probe_track( mallitem * ip )
00215 {
00216    int ii ;
00217    size_t n ;
00218    char * fred ;
00219 
00220    if( ip == NULL ){ pr_nam=NULL; return; } /* error */
00221    fred = (char *) ip->pmt ; if( fred == NULL ){ pr_nam=NULL; return; }
00222    n = ip->psz ;
00223 
00224    for( ii=0 ; ii < NEXTRA ; ii++ )
00225       if( fred[ii] != MAGIC ){
00226          fprintf(stderr,"*** MCW_malloc pre-corruption!  "
00227                         "serial=%u size=%d source=%s line#%d",
00228                         ip->pss,(int)ip->psz,ip->pfn,ip->pln ) ;
00229 #ifdef USE_TRACING
00230          { int tt ;
00231            for( tt=0 ; tt < NTB && ip->ptb[tt] != NULL ; tt++ )
00232              fprintf(stderr," <- %s",ip->ptb[tt]) ;
00233          }
00234 #endif
00235          fprintf(stderr,"\n") ;
00236 
00237          if( pr_nam != NULL )
00238           fprintf(stderr," [[ Called from source=%.50s line#%d ]]\n",pr_nam,pr_lin);
00239          break ;
00240       }
00241 
00242    for( ii=0 ; ii < NEXTRA ; ii++ )
00243       if( fred[n+NEXTRA+ii] != MAGIC ){
00244          fprintf(stderr,"*** MCW_malloc post-corruption!  "
00245                         "serial=%u size=%d source=%s line#%d\n",
00246                         ip->pss,(int)ip->psz,ip->pfn,ip->pln ) ;
00247 #ifdef USE_TRACING
00248          { int tt ;
00249            for( tt=0 ; tt < NTB && ip->ptb[tt] != NULL ; tt++ )
00250              fprintf(stderr," <- %s",ip->ptb[tt]) ;
00251          }
00252 #endif
00253          fprintf(stderr,"\n") ;
00254 
00255          if( pr_nam != NULL )
00256           fprintf(stderr," [[ Called from source=%.50s line#%d ]]\n",pr_nam,pr_lin);
00257          break ;
00258       }
00259 
00260    pr_nam = NULL ;  /* reset */
00261    return ;
00262 }
00263 
00264 /*-------------------------------------------------------------------
00265   The tracking replacement for realloc
00266 ---------------------------------------------------------------------*/
00267 
00268 static void * realloc_track( mallitem * ip, size_t n, char * fn, int ln )
00269 {
00270    char * nfred , * cfred ;
00271    size_t nn = n + 2*NEXTRA ;
00272    int ii , cjj,njj , kk ;
00273 
00274    if( ip == NULL ) return NULL ;  /* should not happen */
00275 
00276    pr_nam = (const char *)fn ; pr_lin = ln ;
00277    probe_track(ip) ;  /* check for integrity before reallocation */
00278    cfred = ip->pmt ;  /* old address */
00279 
00280    nfred = (char*)realloc( cfred , nn ) ;
00281    if( nfred == NULL ){                                       /* real bad */
00282       fprintf(stderr,
00283               "\n*** MCW_realloc(%d) from %s#%d FAILS!\a\n",  /* 02 Jan 2002 */
00284               (int)n , fn , ln ) ;
00285       return NULL ;
00286    }
00287 
00288    for( ii=0 ; ii < NEXTRA ; ii++ )
00289       nfred[ii] = nfred[n+NEXTRA+ii] = MAGIC ;
00290 
00291    cjj = mallkey(cfred) % SLOTS ;  /* hash table list for old */
00292    njj = mallkey(nfred) % SLOTS ;  /* and for new address */
00293 
00294    if( cjj == njj ){  /* can just update old hashtable entry */
00295 
00296       ip->pmt = nfred ;
00297       ip->psz = n ;
00298       ip->pfn = fn ;
00299       ip->pln = ln ;
00300       ip->pss = ++serial ;
00301 
00302       ADD_TRACEBACK(ip) ;  /* 16 Feb 2001 */
00303 
00304    } else {           /* must move into a different list */
00305 
00306       add_tracker( nfred , n , fn , ln ) ;
00307 
00308       ip->pmt = NULL ; /* mark old entry as free */
00309    }
00310 
00311    return (void *)(nfred+NEXTRA) ;
00312 }
00313 
00314 /*-----------------------------------------------------------------
00315   Tracking replacement for calloc
00316 -------------------------------------------------------------------*/
00317 
00318 static void * calloc_track( size_t n , size_t m , char * fn , int ln )
00319 {
00320    void * fred ;
00321    size_t nn = n*m ;
00322 
00323    fred = malloc_track(nn,fn,ln) ; if( fred == NULL ) return NULL ;
00324    memset( fred , 0 , nn ) ;
00325    return fred ;
00326 }
00327 
00328 /*-----------------------------------------------------------------
00329   Tracking replacement for free
00330 -------------------------------------------------------------------*/
00331 
00332 static void free_track( mallitem * ip )
00333 {
00334    char * cfred ;
00335 
00336    if( ip == NULL ) return ;
00337    cfred = (char *) ip->pmt ;
00338    if( cfred == NULL ) return ;
00339 
00340    pr_nam = NULL ;
00341    probe_track(ip) ;  /* check for integrity before freeing */
00342 
00343    free(cfred) ; ip->pmt = NULL ; return ;
00344 }
00345 
00346 /*-----------------------------------------------------------------
00347   Return a status line about the situation
00348 -------------------------------------------------------------------*/
00349 
00350 static int use_tracking = 0 ;  /* is the tracking enabled? */
00351 
00352 char * mcw_malloc_status(const char *fn , int ln)
00353 {
00354    static char buf[128] = "\0" ;
00355    int jj,kk , nptr=0 ; size_t nbyt=0 ;
00356 
00357    if( ! use_tracking ) return NULL ;
00358 
00359    for( jj=0 ; jj < SLOTS ; jj++ ){
00360       for( kk=0 ; kk < nhtab[jj] ; kk++ ){
00361          if( htab[jj][kk].pmt != NULL ){
00362             pr_nam = (const char *)fn ; pr_lin = ln ;
00363             probe_track( htab[jj]+kk ) ; /* check for integrity */
00364             nptr++ ; nbyt += htab[jj][kk].psz ;
00365          }
00366       }
00367    }
00368 
00369    sprintf(buf,"chunks=%d bytes=%u",nptr,(UINT)nbyt) ;
00370    return buf ;
00371 }
00372 
00373 /*-----------------------------------------------------------------
00374   Write a file with lots of info about the current status
00375 -------------------------------------------------------------------*/
00376 
00377 extern int THD_is_file( char * ) ;
00378 extern void qsort_intint( int , int * , int * ) ;
00379 
00380 void mcw_malloc_dump(void)
00381 {
00382    int ii,jj,kk ;
00383    char fname[32] , * str ;
00384    FILE * fp = NULL ;
00385    int nptr=0 ;
00386    int * ss , * jk ;
00387 
00388    if( ! use_tracking ) return ;
00389 
00390    /* find and open an output file */
00391 
00392    for( ii=1 ; ii < 1000 ; ii++ ){
00393       sprintf(fname,"malldump.%03d",ii) ;
00394       if( THD_is_file(fname) ) continue ;
00395       fp = fopen( fname , "w" ) ;
00396       if( fp == NULL ){
00397          fprintf(stderr,"** Unable to open file %s for malloc table dump!\n",
00398                  fname ) ;
00399          return ;
00400       }
00401       break ;
00402    }
00403 
00404    if( fp == NULL ){
00405       fprintf(stderr,"** Attempt to exceed 999 malloc table dump files!\n") ;
00406       return ;
00407    }
00408 
00409    /* count number of entries in the hash table */
00410 
00411    for( jj=0 ; jj < SLOTS ; jj++ ){
00412       for( kk=0 ; kk < nhtab[jj] ; kk++ ){
00413          if( htab[jj][kk].pmt != NULL ) nptr++ ;
00414       }
00415    }
00416 
00417    if( nptr < 1 ){
00418       fprintf(fp    ,"--- Nothing is malloc()-ed !? ---\n") ;
00419       fprintf(stderr,"--- Nothing is malloc()-ed !? ---\n") ;
00420       fclose(fp) ;
00421    }
00422 
00423    /* setup to sort by serial number */
00424 
00425    ss = (int *) malloc(sizeof(int)*nptr) ;  /* serial number */
00426    jk = (int *) malloc(sizeof(int)*nptr) ;  /* holds combination of jj and kk */
00427 
00428 #define JBASE 32768  /* JBASE * SLOTS must be less than max int */
00429 
00430    /* scan table for non-NULL entries */
00431 
00432    for( ii=jj=0 ; jj < SLOTS ; jj++ ){
00433       for( kk=0 ; kk < nhtab[jj] ; kk++ ){
00434          if( htab[jj][kk].pmt != NULL ){
00435             ss[ii] = htab[jj][kk].pss ;   /* save serial number */
00436             jk[ii] = JBASE*jj + kk ;      /* save jj and kk */
00437             ii++ ;
00438          }
00439       }
00440    }
00441 
00442    qsort_intint( nptr , ss , jk ) ;  /* sort by ss, carrying jk along */
00443 
00444    /* now print table in serial number order */
00445 
00446 #ifdef USE_TRACING
00447    fprintf(fp, "MCW Malloc Table Dump:\n"
00448                "serial# size       source file          line# address    hash(j,k) <- Called by\n"
00449                "------- ---------- -------------------- ----- ---------- ----- ---    ---------\n");
00450 #else
00451    fprintf(fp, "MCW Malloc Table Dump:\n"
00452                "serial# size       source file          line# address    hash(j,k)\n"
00453                "------- ---------- -------------------- ----- ---------- ----- ---\n") ;
00454 #endif
00455 
00456    for( ii=0 ; ii < nptr ; ii++ ){
00457       jj = jk[ii] / JBASE ;           /* retrieve jj and kk */
00458       kk = jk[ii] % JBASE ;
00459       if( htab[jj][kk].pmt != NULL ){
00460          fprintf(fp,"%7u %10d %-20.30s %5d %10p %5d %3d",
00461                  htab[jj][kk].pss , (int)htab[jj][kk].psz ,
00462                  htab[jj][kk].pfn , htab[jj][kk].pln , htab[jj][kk].pmt ,
00463                  jj,kk ) ;
00464 #ifdef USE_TRACING
00465          { int tt ;
00466            for( tt=0 ; tt < NTB && htab[jj][kk].ptb[tt] != NULL ; tt++ )
00467               fprintf(fp," <- %s",htab[jj][kk].ptb[tt]) ;
00468          }
00469 #endif
00470          fprintf(fp,"\n") ;
00471       }
00472       else
00473          fprintf(fp,"*** Error at ii=%d jj=%d kk=%d\n",ii,jj,kk) ;
00474    }
00475 
00476    free(ss) ; free(jk) ;
00477 
00478    /* and print out the summary line (to the file and screen) */
00479 
00480    str = mcw_malloc_status(NULL,0) ;
00481    fprintf(fp,"----- Summary: %s\n",str) ;
00482    fclose(fp) ;
00483 
00484    fprintf(stderr,"** Malloc table dumped to file %s\n",fname) ;
00485    fprintf(stderr,"** Summary: %s\n",str) ;
00486 
00487    return ;
00488 }
00489 
00490 /*----------------------------------------------------------------
00491   Turn on use of the tracking routines
00492 ------------------------------------------------------------------*/
00493 
00494 void enable_mcw_malloc()       /* cannot be disabled */
00495 {
00496    char * str = getenv("AFNI_NO_MCW_MALLOC") ;  /* NOT my_getenv */
00497 
00498    if( use_tracking ) return ;   /* 05 Nov 2001 */
00499 
00500    use_tracking = 1 ;
00501    if( str!=NULL && ( str[0]=='y' || str[0]=='Y') ) use_tracking = 0 ;
00502 
00503    if( use_tracking && htab == NULL ){  /* initialize hash table */
00504       int jj ;
00505       htab  = (mallitem **) malloc( SLOTS * sizeof(mallitem *) ) ;
00506       nhtab = (int *)       malloc( SLOTS * sizeof(int) ) ;
00507       for( jj=0 ; jj < SLOTS ; jj++ ){
00508          htab[jj] = NULL ; nhtab[jj] = 0 ;
00509       }
00510    }
00511 
00512    return ;
00513 }
00514 
00515 /* ---------------------------------------
00516    Force a halt to memory tracking.
00517    the halt is meant to be temporary.
00518    Had to add this for SUMA to get around
00519    the problem of using allocate2D with
00520    large numbers of pointers. ZSS 03/04
00521    --------------------------------------- */
00522 static int pz = 0;   /* flag to indicate pause */
00523 void pause_mcw_malloc()
00524 {
00525    if (pz) return;   /* nothing to do */
00526    if (use_tracking) {
00527       pz = 1;
00528       use_tracking = 0;
00529    }
00530    return;
00531 }    
00532 void resume_mcw_malloc()
00533 {
00534    if (!pz) return; 
00535    pz = 0;
00536    use_tracking = 1;
00537    return;
00538 }
00539 int mcw_malloc_paused()
00540 {
00541    return(pz);
00542 }
00543    
00544 /*---------------------------------------------------------------*/
00545 /*--- lets the user check if the tracking routines are in use ---*/
00546 
00547 int mcw_malloc_enabled(){ return (use_tracking != 0) ; }
00548 
00549 /*-----------------------------------------------------------------
00550    The actual routine that replaces malloc() -- see mcw_malloc.h
00551 -------------------------------------------------------------------*/
00552 
00553 void * mcw_malloc( size_t n , char * fnam , int lnum )
00554 {
00555    if( use_tracking ) return malloc_track(n,fnam,lnum) ;
00556    else               return malloc(n) ;
00557 }
00558 
00559 /*----------------------------------------------------------------
00560    The actual replacement for realloc()
00561 ------------------------------------------------------------------*/
00562 
00563 void * mcw_realloc( void * fred , size_t n , char * fnam , int lnum )
00564 {
00565    mallitem * ip ;
00566 
00567    if( fred == NULL )
00568       return mcw_malloc( n , fnam , lnum ) ;
00569 
00570    if( use_tracking && (ip=shift_tracker(fred)) != NULL )
00571       return realloc_track( ip , n , fnam,lnum ) ;
00572    else
00573       return realloc( fred , n ) ;
00574 }
00575 
00576 /*----------------------------------------------------------------
00577    The actual replacement for calloc()
00578 ------------------------------------------------------------------*/
00579 
00580 void * mcw_calloc( size_t n , size_t m , char * fnam , int lnum )
00581 {
00582    if( use_tracking ) return calloc_track( n , m , fnam,lnum ) ;
00583    else               return calloc( n , m ) ;
00584 }
00585 
00586 /*-----------------------------------------------------------------
00587     The actual replacment for free()
00588 -------------------------------------------------------------------*/
00589 
00590 void mcw_free( void * fred )
00591 {
00592    mallitem * ip ;
00593 
00594    if( fred == NULL ) return ;
00595 
00596    if( use_tracking && (ip=shift_tracker(fred)) != NULL ) free_track( ip ) ;
00597    else                                                   free( fred ) ;
00598 }
00599 
00600 /*-----------------------------------------------------------------
00601    The actual replacement for XtMalloc()
00602 -------------------------------------------------------------------*/
00603 
00604 char * mcw_XtMalloc( Cardinal n , char * fnam , int lnum )
00605 {
00606    if( use_tracking ) return (char *) malloc_track(n,fnam,lnum) ;
00607    else               return (char *)XtMalloc(n) ;
00608 }
00609 
00610 /*-----------------------------------------------------------------
00611    The actual replacement for XtRealloc()
00612 -------------------------------------------------------------------*/
00613 
00614 char * mcw_XtRealloc( char *p, Cardinal n , char * fnam , int lnum )
00615 {
00616    mallitem * ip ;
00617 
00618    if( p == NULL )
00619       return mcw_XtMalloc( n , fnam , lnum ) ;
00620 
00621    if( use_tracking && (ip=shift_tracker(p)) != NULL )
00622       return (char*)realloc_track( ip , n , fnam,lnum ) ;
00623    else
00624       return (char*)XtRealloc( p , n ) ;
00625 }
00626 
00627 /*----------------------------------------------------------------
00628    The actual replacement for XtFree()
00629 ------------------------------------------------------------------*/
00630 
00631 void mcw_XtFree( char *p )
00632 {
00633    mallitem * ip ;
00634 
00635    if( p == NULL ) return ;
00636 
00637    if( use_tracking && (ip=shift_tracker(p)) != NULL ) free_track(ip) ;
00638    else                                                XtFree(p) ;
00639 }
00640 
00641 /*-----------------------------------------------------------------
00642   The actual replacement for XtCalloc()
00643 -------------------------------------------------------------------*/
00644 
00645 char * mcw_XtCalloc( Cardinal n , Cardinal m , char * fnam , int lnum )
00646 {
00647    if( use_tracking ) return (char *) calloc_track( n , m , fnam,lnum ) ;
00648    else               return XtCalloc( n , m ) ;
00649 }
 

Powered by Plone

This site conforms to the following standards: