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/Map.h>
00015 #include <shogun/base/SGObject.h>
00016
00017 using namespace shogun;
00018
00019 #ifdef TRACE_MEMORY_ALLOCS
00020 extern CMap<void*, shogun::MemoryBlock>* sg_mallocs;
00021
00022 MemoryBlock::MemoryBlock() : ptr(NULL), size(0), file(NULL),
00023 line(-1), is_sgobject(false)
00024 {
00025 }
00026
00027 MemoryBlock::MemoryBlock(void* p) : ptr(p), size(0), file(NULL),
00028 line(-1), is_sgobject(false)
00029 {
00030 }
00031
00032 MemoryBlock::MemoryBlock(void* p, size_t sz, const char* fname, int linenr) :
00033 ptr(p), size(sz), file(fname), line(linenr), is_sgobject(false)
00034 {
00035 }
00036
00037 MemoryBlock::MemoryBlock(const MemoryBlock &b)
00038 {
00039 ptr=b.ptr;
00040 size=b.size;
00041 file=b.file;
00042 line=b.line;
00043 is_sgobject=b.is_sgobject;
00044 }
00045
00046
00047 bool MemoryBlock::operator==(const MemoryBlock &b) const
00048 {
00049 return ptr==b.ptr;
00050 }
00051
00052 void MemoryBlock::display()
00053 {
00054 if (line!=-1)
00055 {
00056 printf("Memory block at %p of size %lld bytes (allocated in %s line %d)\n",
00057 ptr, (long long int) size, file, line);
00058 }
00059 else
00060 {
00061 if (is_sgobject)
00062 {
00063 CSGObject* obj=(CSGObject*) ptr;
00064 printf("SGObject '%s' at %p of size %lld bytes with %d ref's\n",
00065 obj->get_name(), obj, (long long int) size, obj->ref_count());
00066 }
00067 else
00068 {
00069 printf("Object at %p of size %lld bytes\n",
00070 ptr, (long long int) size);
00071 }
00072 }
00073 }
00074
00075 void MemoryBlock::set_sgobject()
00076 {
00077 is_sgobject=true;
00078 }
00079 #endif
00080
00081 void* operator new(size_t size) throw (std::bad_alloc)
00082 {
00083 void *p=malloc(size);
00084 #ifdef TRACE_MEMORY_ALLOCS
00085 if (sg_mallocs)
00086 sg_mallocs->add(p, MemoryBlock(p,size));
00087 #endif
00088 if (!p)
00089 {
00090 const size_t buf_len=128;
00091 char buf[buf_len];
00092 size_t written=snprintf(buf, buf_len,
00093 "Out of memory error, tried to allocate %lld bytes using new().\n", (long long int) size);
00094 if (written<buf_len)
00095 throw ShogunException(buf);
00096 else
00097 throw ShogunException("Out of memory error using new.\n");
00098 }
00099
00100 return p;
00101 }
00102
00103 void operator delete(void *p) throw()
00104 {
00105 #ifdef TRACE_MEMORY_ALLOCS
00106 if (sg_mallocs)
00107 sg_mallocs->remove(p);
00108 #endif
00109 free(p);
00110 }
00111
00112 void* operator new[](size_t size) throw(std::bad_alloc)
00113 {
00114 void *p=malloc(size);
00115 #ifdef TRACE_MEMORY_ALLOCS
00116 if (sg_mallocs)
00117 sg_mallocs->add(p, MemoryBlock(p,size));
00118 #endif
00119
00120 if (!p)
00121 {
00122 const size_t buf_len=128;
00123 char buf[buf_len];
00124 size_t written=snprintf(buf, buf_len,
00125 "Out of memory error, tried to allocate %lld bytes using new[].\n", (long long int) size);
00126 if (written<buf_len)
00127 throw ShogunException(buf);
00128 else
00129 throw ShogunException("Out of memory error using new[].\n");
00130 }
00131
00132 return p;
00133 }
00134
00135 void operator delete[](void *p) throw()
00136 {
00137 #ifdef TRACE_MEMORY_ALLOCS
00138 if (sg_mallocs)
00139 sg_mallocs->remove(p);
00140 #endif
00141 free(p);
00142 }
00143
00144 void* sg_malloc(size_t size
00145 #ifdef TRACE_MEMORY_ALLOCS
00146 , const char* file, int line
00147 #endif
00148 )
00149 {
00150 void* p=malloc(size);
00151 #ifdef TRACE_MEMORY_ALLOCS
00152 if (sg_mallocs)
00153 sg_mallocs->add(p, MemoryBlock(p,size, file, line));
00154 #endif
00155
00156 if (!p)
00157 {
00158 const size_t buf_len=128;
00159 char buf[buf_len];
00160 size_t written=snprintf(buf, buf_len,
00161 "Out of memory error, tried to allocate %lld bytes using malloc.\n", (long long int) size);
00162 if (written<buf_len)
00163 throw ShogunException(buf);
00164 else
00165 throw ShogunException("Out of memory error using malloc.\n");
00166 }
00167
00168 return p;
00169 }
00170
00171 void* sg_calloc(size_t num, size_t size
00172 #ifdef TRACE_MEMORY_ALLOCS
00173 , const char* file, int line
00174 #endif
00175 )
00176 {
00177 void* p=calloc(num, size);
00178 #ifdef TRACE_MEMORY_ALLOCS
00179 if (sg_mallocs)
00180 sg_mallocs->add(p, MemoryBlock(p,size, file, line));
00181 #endif
00182
00183 if (!p)
00184 {
00185 const size_t buf_len=128;
00186 char buf[buf_len];
00187 size_t written=snprintf(buf, buf_len,
00188 "Out of memory error, tried to allocate %lld bytes using calloc.\n",
00189 (long long int) size);
00190
00191 if (written<buf_len)
00192 throw ShogunException(buf);
00193 else
00194 throw ShogunException("Out of memory error using calloc.\n");
00195 }
00196
00197 return p;
00198 }
00199
00200 void sg_free(void* ptr)
00201 {
00202 #ifdef TRACE_MEMORY_ALLOCS
00203 if (sg_mallocs)
00204 sg_mallocs->remove(ptr);
00205 #endif
00206 free(ptr);
00207 }
00208
00209 void* sg_realloc(void* ptr, size_t size
00210 #ifdef TRACE_MEMORY_ALLOCS
00211 , const char* file, int line
00212 #endif
00213 )
00214 {
00215 void* p=realloc(ptr, size);
00216
00217 #ifdef TRACE_MEMORY_ALLOCS
00218 if (sg_mallocs)
00219 sg_mallocs->remove(ptr);
00220
00221 if (sg_mallocs)
00222 sg_mallocs->add(p, MemoryBlock(p,size, file, line));
00223 #endif
00224
00225 if (!p && (size || !ptr))
00226 {
00227 const size_t buf_len=128;
00228 char buf[buf_len];
00229 size_t written=snprintf(buf, buf_len,
00230 "Out of memory error, tried to allocate %lld bytes using realloc.\n", (long long int) size);
00231 if (written<buf_len)
00232 throw ShogunException(buf);
00233 else
00234 throw ShogunException("Out of memory error using realloc.\n");
00235 }
00236
00237 return p;
00238 }
00239
00240 #ifdef TRACE_MEMORY_ALLOCS
00241 void list_memory_allocs()
00242 {
00243 MemoryBlock* temp;
00244 if (sg_mallocs)
00245 {
00246 int32_t num=sg_mallocs->get_num_elements();
00247 int32_t size=sg_mallocs->get_array_size();
00248 printf("%d Blocks are allocated:\n", num);
00249
00250
00251 for (int32_t i=0; i<size; i++)
00252 {
00253 temp=sg_mallocs->get_element_ptr(i);
00254 if (temp!=NULL)
00255 temp->display();
00256 }
00257 }
00258 }
00259 #endif