SHOGUN
v2.0.0
|
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/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