memory.cpp

Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 2008-2009 Soeren Sonnenburg
00008  * Copyright (C) 2008-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00009  */
00010 
00011 #include <shogun/lib/ShogunException.h>
00012 #include <shogun/lib/memory.h>
00013 #include <shogun/lib/common.h>
00014 #include <shogun/lib/Set.h>
00015 #include <shogun/base/SGObject.h>
00016 
00017 using namespace shogun;
00018 
00019 #ifdef TRACE_MEMORY_ALLOCS
00020 extern CSet<shogun::MemoryBlock>* sg_mallocs;
00021 
00022 MemoryBlock::MemoryBlock(void* p) : ptr(p), size(0), file(NULL),
00023     line(-1), is_sgobject(false)
00024 {
00025 }
00026 
00027 MemoryBlock::MemoryBlock(void* p, size_t sz, const char* fname, int linenr) :
00028     ptr(p), size(sz), file(fname), line(linenr), is_sgobject(false)
00029 {
00030 }
00031 
00032 MemoryBlock::MemoryBlock(const MemoryBlock &b)
00033 {
00034     ptr=b.ptr;
00035     size=b.size;
00036     file=b.file;
00037     line=b.line;
00038     is_sgobject=b.is_sgobject;
00039 }
00040 
00041 
00042 bool MemoryBlock::operator==(const MemoryBlock &b) const
00043 {
00044     return ptr==b.ptr;
00045 }
00046 
00047 void MemoryBlock::display()
00048 {
00049     if (line!=-1)
00050     {
00051         printf("Memory block at %p of size %lld bytes (allocated in %s line %d)\n",
00052                 ptr, (long long int) size, file, line);
00053     }
00054     else
00055     {
00056         if (is_sgobject)
00057         {
00058             CSGObject* obj=(CSGObject*) ptr;
00059             printf("SGObject '%s' at %p of size %lld bytes with %d ref's\n",
00060                     obj->get_name(), obj, (long long int) size, obj->ref_count());
00061         }
00062         else
00063         {
00064             printf("Object at %p of size %lld bytes\n",
00065                     ptr, (long long int) size);
00066         }
00067     }
00068 }
00069 
00070 void MemoryBlock::set_sgobject()
00071 {
00072     is_sgobject=true;
00073 }
00074 #endif
00075 
00076 void* operator new(size_t size) throw (std::bad_alloc)
00077 {
00078     void *p=malloc(size);
00079 #ifdef TRACE_MEMORY_ALLOCS
00080     if (sg_mallocs)
00081         sg_mallocs->add(MemoryBlock(p,size));
00082 #endif
00083     if (!p)
00084     {
00085         const size_t buf_len=128;
00086         char buf[buf_len];
00087         size_t written=snprintf(buf, buf_len,
00088             "Out of memory error, tried to allocate %lld bytes using new().\n", (long long int) size);
00089         if (written<buf_len)
00090             throw ShogunException(buf);
00091         else
00092             throw ShogunException("Out of memory error using new.\n");
00093     }
00094 
00095     return p;
00096 }
00097 
00098 void operator delete(void *p) throw()
00099 {
00100 #ifdef TRACE_MEMORY_ALLOCS
00101     if (sg_mallocs)
00102         sg_mallocs->remove(MemoryBlock(p, true));
00103 #endif
00104     free(p);
00105 }
00106 
00107 void* operator new[](size_t size) throw(std::bad_alloc)
00108 {
00109     void *p=malloc(size);
00110 #ifdef TRACE_MEMORY_ALLOCS
00111     if (sg_mallocs)
00112         sg_mallocs->add(MemoryBlock(p,size));
00113 #endif
00114 
00115     if (!p)
00116     {
00117         const size_t buf_len=128;
00118         char buf[buf_len];
00119         size_t written=snprintf(buf, buf_len,
00120             "Out of memory error, tried to allocate %lld bytes using new[].\n", (long long int) size);
00121         if (written<buf_len)
00122             throw ShogunException(buf);
00123         else
00124             throw ShogunException("Out of memory error using new[].\n");
00125     }
00126 
00127     return p;
00128 }
00129 
00130 void operator delete[](void *p) throw()
00131 {
00132 #ifdef TRACE_MEMORY_ALLOCS
00133     if (sg_mallocs)
00134         sg_mallocs->remove(MemoryBlock(p, false));
00135 #endif
00136     free(p);
00137 }
00138 
00139 void* sg_malloc(size_t size
00140 #ifdef TRACE_MEMORY_ALLOCS
00141         , const char* file, int line
00142 #endif
00143 )
00144 {
00145     void* p=malloc(size);
00146 #ifdef TRACE_MEMORY_ALLOCS
00147     if (sg_mallocs)
00148         sg_mallocs->add(MemoryBlock(p,size, file, line));
00149 #endif
00150 
00151     if (!p)
00152     {
00153         const size_t buf_len=128;
00154         char buf[buf_len];
00155         size_t written=snprintf(buf, buf_len,
00156             "Out of memory error, tried to allocate %lld bytes using malloc.\n", (long long int) size);
00157         if (written<buf_len)
00158             throw ShogunException(buf);
00159         else
00160             throw ShogunException("Out of memory error using malloc.\n");
00161     }
00162 
00163     return p;
00164 }
00165 
00166 void* sg_calloc(size_t num, size_t size
00167 #ifdef TRACE_MEMORY_ALLOCS
00168         , const char* file, int line
00169 #endif
00170 )
00171 {
00172     void* p=calloc(num, size);
00173 #ifdef TRACE_MEMORY_ALLOCS
00174     if (sg_mallocs)
00175         sg_mallocs->add(MemoryBlock(p,size, file, line));
00176 #endif
00177 
00178     if (!p)
00179     {
00180         const size_t buf_len=128;
00181         char buf[buf_len];
00182         size_t written=snprintf(buf, buf_len,
00183             "Out of memory error, tried to allocate %lld bytes using calloc.\n",
00184             (long long int) size);
00185 
00186         if (written<buf_len)
00187             throw ShogunException(buf);
00188         else
00189             throw ShogunException("Out of memory error using calloc.\n");
00190     }
00191 
00192     return p;
00193 }
00194 
00195 void  sg_free(void* ptr)
00196 {
00197 #ifdef TRACE_MEMORY_ALLOCS
00198     if (sg_mallocs)
00199         sg_mallocs->remove(MemoryBlock(ptr, false));
00200 #endif
00201     free(ptr);
00202 }
00203 
00204 void* sg_realloc(void* ptr, size_t size
00205 #ifdef TRACE_MEMORY_ALLOCS
00206         , const char* file, int line
00207 #endif
00208 )
00209 {
00210     void* p=realloc(ptr, size);
00211 
00212 #ifdef TRACE_MEMORY_ALLOCS
00213     if (sg_mallocs)
00214         sg_mallocs->remove(MemoryBlock(ptr, false));
00215 
00216     if (sg_mallocs)
00217         sg_mallocs->add(MemoryBlock(p,size, file, line));
00218 #endif
00219 
00220     if (!p && (size || !ptr))
00221     {
00222         const size_t buf_len=128;
00223         char buf[buf_len];
00224         size_t written=snprintf(buf, buf_len,
00225             "Out of memory error, tried to allocate %lld bytes using realloc.\n", (long long int) size);
00226         if (written<buf_len)
00227             throw ShogunException(buf);
00228         else
00229             throw ShogunException("Out of memory error using realloc.\n");
00230     }
00231 
00232     return p;
00233 }
00234 
00235 #ifdef TRACE_MEMORY_ALLOCS
00236 void list_memory_allocs()
00237 {
00238     if (sg_mallocs)
00239     {
00240         int32_t num=sg_mallocs->get_num_elements();
00241         printf("%d Blocks are allocated:\n", num);
00242 
00243 
00244         for (int32_t i=0; i<num; i++)
00245             sg_mallocs->get_element(i).display();
00246     }
00247 }
00248 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation