Eneboo - Documentación para desarrolladores
|
00001 /* -*- C++ -*- */ 00002 00003 #include <map> 00004 #include "stlallocator.h" 00005 00006 #ifndef _SANITYCHECKHEAP_H_ 00007 #define _SANITYCHECKHEAP_H_ 00008 00016 #include "mallocheap.h" 00017 #include "zoneheap.h" 00018 #include "stlallocator.h" 00019 #include "mmapheap.h" 00020 00021 namespace HL { 00022 00023 template <class SuperHeap> 00024 class SanityCheckHeap : public SuperHeap { 00025 private: 00026 00029 00030 // The objects are pairs, mapping void * pointers to sizes. 00031 typedef std::pair<const void *, int> objType; 00032 00033 // The heap is a simple freelist heap. 00034 typedef HL::FreelistHeap<HL::ZoneHeap<HL::MmapHeap, 16384> > heapType; 00035 00036 // And we wrap it up so it can be used as an STL allocator. 00037 typedef HL::STLAllocator<objType, heapType> localAllocator; 00038 00039 typedef std::less<void *> localComparator; 00040 00042 typedef std::map<void *, int, localComparator, localAllocator> mapType; 00043 00045 enum { FREED = -1 }; 00046 00051 enum { MALLOC_RETURNED_ALLOCATED_OBJECT = 0, 00052 FREE_CALLED_ON_OBJECT_I_NEVER_ALLOCATED = 0, 00053 FREE_CALLED_TWICE_ON_SAME_OBJECT = 0 }; 00054 00055 public: 00056 00057 inline void * malloc (size_t sz) { 00058 void * ptr = SuperHeap::malloc (sz); 00059 if (ptr == NULL) { 00060 return NULL; 00061 } 00062 // Fill the space with a known value. 00063 memset (ptr, 'A', sz); 00064 // Record this object as allocated. 00065 mapType::iterator i; 00066 // Look for this object in the map of allocated objects. 00067 i = allocatedObjects.find (ptr); 00068 if (i == allocatedObjects.end()) { 00069 // We didn't find it (this is good). 00070 // Add the tuple (ptr, sz). 00071 allocatedObjects.insert (std::pair<void *, int>(ptr, sz)); 00072 } else { 00073 // We found it. 00074 // It really should have been freed. 00075 if ((*i).second != FREED) { 00076 // This object is still in use! 00077 assert ( MALLOC_RETURNED_ALLOCATED_OBJECT ); 00078 return NULL; 00079 } else { 00080 // This object has been freed. Mark it as allocated. 00081 (*i).second = sz; 00082 } 00083 } 00084 return ptr; 00085 } 00086 00087 inline void free (void * ptr) { 00088 // Look for this object in the list of allocated objects. 00089 mapType::iterator i; 00090 i = allocatedObjects.find (ptr); 00091 if (i == allocatedObjects.end()) { 00092 assert ( FREE_CALLED_ON_OBJECT_I_NEVER_ALLOCATED ); 00093 return; 00094 } 00095 // We found the object. It should not have been freed already. 00096 if ((*i).second == FREED) { 00097 // Oops, this object WAS freed before. 00098 assert ( FREE_CALLED_TWICE_ON_SAME_OBJECT ); 00099 return; 00100 } 00101 // Fill the space with a known value. 00102 memset (ptr, 'F', (*i).second); 00103 // Really free the pointer. 00104 (*i).second = FREED; 00105 SuperHeap::free (ptr); 00106 } 00107 00108 private: 00109 00111 mapType allocatedObjects; 00112 }; 00113 00114 }; 00115 00116 #endif