xmalloc.c

Go to the documentation of this file.
00001 /*
00002  * mplib - a library that enables you to edit ID3 tags
00003  *
00004  * Copyright (c) 2001,2002,2003,2004,2005 Stefan Podkowinski
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without 
00008  * modification, are permitted provided that the following conditions are met:
00009  *
00010  * * Redistributions of source code must retain the above copyright notice, this
00011  *   list of conditions and the following disclaimer.
00012  * * Redistributions in binary form must reproduce the above copyright notice,
00013  *   this list of conditions and the following disclaimer in the documentation
00014  *   and/or other materials provided with the distribution.
00015  * * Neither the name of the author nor the names of its contributors
00016  *   may be used to endorse or promote products derived from this software
00017  *   without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00023  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029  * POSSIBILITY OF SUCH DAMAGE.
00030  */
00031 
00032 #include <sys/types.h>
00033 #include <stdio.h>
00034 /* define XMALLOC_CHECK 1 */
00035 #include "xmalloc.h"
00036 #ifdef USE_GC
00037 # include <gc.h>
00038 # define malloc(str) GC_MALLOC(str)
00039 #endif
00040 
00041 #ifdef XMALLOC_CHECK
00042 typedef struct _xdelem {
00043     void* alloced;
00044     void* freed;
00045     char* descrl;
00046     struct _xdelem* next;
00047 } xdelem;
00048 
00049 xdelem* first = NULL;
00050 #endif
00051 
00052 #define errmsg "mplib: Memory exhausted: Could not allocate %d bytes\n"
00053 
00054 void *
00055 xmalloc(size_t s)
00056 {
00057     return xmallocd(s, NULL);
00058 }
00059 
00060 void *
00061 xmallocd(size_t s, char* descrl)
00062 {
00063   void *new = (void*)malloc(s);
00064 #ifdef XMALLOC_CHECK
00065   xdelem* cur = (xdelem*)malloc(sizeof(xdelem));
00066   cur->next = NULL;
00067   cur->freed = NULL;
00068   cur->descrl = descrl;
00069 #endif
00070   if(!new) fprintf(stderr, errmsg, s);
00071 
00072 #ifdef XMALLOC_CHECK
00073   cur->alloced = new;
00074  exists:
00075   if(!first) first = cur;
00076   else {
00077       xdelem* last = first;
00078       do {
00079           if(last->alloced == cur->alloced) {
00080               last->freed = NULL;
00081               last->descrl = descrl;
00082               free(cur);
00083               goto exists;
00084           }
00085       } while(last->next && (last = last->next));
00086       last->next = cur;
00087   }
00088 #endif
00089 
00090   return new;
00091 }
00092 
00093 void *
00094 xmallocd0(size_t s, char* descr)
00095 {
00096 #ifdef XMALLOC_CHECK
00097     void *new = (void*)xmallocd(s, descr);
00098 #else
00099     void *new = (void*)malloc(s);
00100 #endif
00101     if(!new) fprintf(stderr, errmsg, s);
00102     else memset(new, 0, s);
00103     return new;
00104 }
00105 
00106 void *
00107 xmalloc0(size_t s)
00108 {
00109 #ifdef XMALLOC_CHECK
00110   void *new = (void*)xmalloc(s);
00111 #else
00112   void *new = (void*)malloc(s);
00113 #endif
00114   if(!new) fprintf(stderr, errmsg, s);
00115   else memset(new, 0, s);
00116   return new;
00117 }
00118 
00119 void *
00120 xrealloc(void * ptr, size_t s)
00121 {
00122   void *new;
00123 
00124   if(!ptr) return xmalloc(s);
00125 
00126   new = (void*)realloc(ptr, s);
00127   if(!new) fprintf(stderr, errmsg, s);
00128   return new;
00129 }
00130 
00131 void
00132 xfree(void* ptr) {
00133     if(!ptr) return;
00134 #ifdef XMALLOC_CHECK
00135     if(first) {
00136         xdelem* el = first;
00137         do {
00138             if(el->freed == ptr) {
00139                 if(el->descrl)
00140                     printf("XMALLOC: (%s) memory allready freed\n", el->descrl);
00141                 else
00142                     printf("XMALLOC: memory allready freed at %h\n", ptr);
00143                 break;
00144             }
00145             if(el->alloced == ptr) {
00146                 el->freed = ptr;
00147                 break;
00148             }
00149         } while(el->next && (el = el->next));
00150     }
00151 #endif
00152     free(ptr);
00153 }
00154 
00155 
00156 #ifdef XMALLOC_CHECK
00157 void
00158 xprint_malloc_stat(void) {
00159     long kb_alloc = 0;
00160     long kb_freed = 0;
00161     long kb_used = 0;
00162     int count_used = 0;
00163     xdelem* el = first;
00164 
00165     if(!first) {
00166         puts("XMALLOC: No statistic available");
00167     }
00168     puts("xmalloc statistic:");
00169     do {        
00170         if(!el->freed) {
00171             if(el->descrl && !strstr(el->descrl, "ignore")) 
00172                 printf("%s (not freed)\n", el->descrl);
00173             else if(!el->descrl) printf("%p (not freed)\n", el->alloced);
00174         } else {
00175             //if(el->descrl) printf("%s (freed)\n", el->descrl);
00176             //else printf("%p (freed)\n", el->alloced);
00177         }
00178     } while(el->next && (el = el->next));
00179 }
00180 #endif