00001
00002
00003
00004
00005
00006
00007
00008
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