SHOGUN
v1.1.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/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