KMemory.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #ifndef __KANJIMEMORY_H__
  2. #define __KANJIMEMORY_H__
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #if defined(_DEBUG) && !defined(KANJI_MEMTRACE)
  6. #define KANJI_MEMTRACE
  7. #endif
  8. #ifdef WIN32
  9. #pragma warning(disable : 4595)
  10. #endif
  11. //////////////////////////////////////////////////////////////////////////
  12. // HOW TO USE THIS FILE
  13. //
  14. // In the desired .CPP file (NOT header file), AFTER ALL of your
  15. // #include declarations, do a #include "KMemory.h" or whatever you renamed
  16. // this file to. It's very important that you do it only in the .cpp and
  17. // after every other include file, otherwise it won't compile. The memory leaks
  18. // will appear in a file called mem_leaks.txt and they will also be printed out
  19. // in the output window when the program exits.
  20. //
  21. //////////////////////////////////////////////////////////////////////////
  22. #ifndef SAFE_DELETE
  23. #define SAFE_DELETE(pPtr) { if(pPtr) delete pPtr; pPtr = 0; }
  24. #endif
  25. #ifndef SCOPED_AUTO_SAFE_DELETE
  26. template<typename T>
  27. class ScopedAutoDeletePointerHelper {
  28. public:
  29. ScopedAutoDeletePointerHelper(T pPtr) : _pPtr(pPtr) {}
  30. ~ScopedAutoDeletePointerHelper() {SAFE_DELETE(_pPtr); }
  31. T _pPtr;
  32. };
  33. #define SCOPED_AUTO_SAFE_DELETE(p) ScopedAutoDeletePointerHelper<decltype(p)> anAutoDelete##p(p);
  34. #endif
  35. #ifndef SAFE_DELETE_ARRAY
  36. #define SAFE_DELETE_ARRAY(pPtr) { if(pPtr) delete [] pPtr; pPtr = 0; }
  37. #endif
  38. extern void KMemoryDumpUnfreed();
  39. extern size_t KMemoryAllocated();
  40. #ifdef WIN32
  41. #define KMEM_CALLTYPE __cdecl
  42. #else
  43. #define KMEM_CALLTYPE
  44. #endif
  45. #ifdef __APPLE__
  46. #define KMEM_THROWSPEC throw(std::bad_alloc)
  47. #define KMEM_THROWS_BADALLOC
  48. #include <new>
  49. #else
  50. #define KMEM_THROWSPEC
  51. #endif
  52. #if defined(KANJI_MEMTRACE)
  53. /////////////////////////////////////////////
  54. // DO NOT CALL THESE TWO METHODS DIRECTLY //
  55. /////////////////////////////////////////////
  56. extern void KMemoryAddTrack(void *addr, size_t asize, const char *fname, int lnum);
  57. extern void KMemoryRemoveTrack(void *addr);
  58. //Replacement for the standard malloc/free, records size of allocation and the file/line number it was on
  59. inline void *_kanjimalloc(size_t size, const char *file, int line) {
  60. void *ptr = (void *) malloc(size);
  61. KMemoryAddTrack(ptr, size, file, line);
  62. return (ptr);
  63. }
  64. inline void *_kanjimalloc(size_t size) {
  65. return _kanjimalloc(size, "", 0);
  66. }
  67. inline void _kanjifree(void *ptr) {
  68. KMemoryRemoveTrack(ptr);
  69. free(ptr);
  70. }
  71. inline void *_kanjirealloc(void *ptr, size_t size, const char *file, int line) {
  72. void *ptr2 = (void *) realloc(ptr, size);
  73. if (ptr2) {
  74. KMemoryRemoveTrack(ptr);
  75. KMemoryAddTrack(ptr2, size, file, line);
  76. }
  77. return ptr2;
  78. }
  79. inline void *_kanjirealloc(void *ptr, size_t size) {
  80. return _kanjirealloc(ptr, size, "", 0);
  81. }
  82. #define kanjimalloc(size) _kanjimalloc((size), __FILE__, __LINE__)
  83. #define kanjifree _kanjifree
  84. #define kanjirealloc(ptr, size) _kanjirealloc(ptr, size, __FILE__, __LINE__)
  85. //Replacement for the standard "new" operator, records size of allocation and the file/line number it was on
  86. inline void *KMEM_CALLTYPE operator new(size_t size, const char *file, int line) {
  87. void *ptr = (void *) malloc(size);
  88. KMemoryAddTrack(ptr, size, file, line);
  89. return (ptr);
  90. }
  91. //Same as above, but for arrays
  92. inline void *KMEM_CALLTYPE operator new[](size_t size, const char *file, int line) {
  93. void *ptr = (void *) malloc(size);
  94. KMemoryAddTrack(ptr, size, file, line);
  95. return (ptr);
  96. }
  97. // These single argument new operators allow vc6 apps to compile without errors
  98. inline void *KMEM_CALLTYPE operator new(size_t size) KMEM_THROWSPEC {
  99. void *ptr = (void *) malloc(size);
  100. #ifdef KMEM_THROWS_BADALLOC
  101. if (!ptr) throw std::bad_alloc();
  102. #endif
  103. return (ptr);
  104. }
  105. inline void *KMEM_CALLTYPE operator new[](size_t size) KMEM_THROWSPEC {
  106. void *ptr = (void *) malloc(size);
  107. #ifdef KMEM_THROWS_BADALLOC
  108. if (!ptr) throw std::bad_alloc();
  109. #endif // KMEM_THROWS_BADALLOC
  110. return (ptr);
  111. }
  112. //custom delete operators
  113. inline void KMEM_CALLTYPE operator delete(void *p) throw() {
  114. KMemoryRemoveTrack(p);
  115. free(p);
  116. }
  117. inline void KMEM_CALLTYPE operator delete[](void *p) throw() {
  118. KMemoryRemoveTrack(p);
  119. free(p);
  120. }
  121. //needed in case in the constructor of the class we're newing, it throws an exception
  122. inline void KMEM_CALLTYPE operator delete(void *pMem, const char *file, int line) {
  123. free(pMem);
  124. }
  125. inline void KMEM_CALLTYPE operator delete[](void *pMem, const char *file, int line) {
  126. free(pMem);
  127. }
  128. #define KDEBUG_NEW new(__FILE__, __LINE__)
  129. #define new KDEBUG_NEW
  130. #else // KANJI_MEMTRACE NOT DEFINED
  131. #define kanjimalloc malloc
  132. #define kanjifree free
  133. #define kanjirealloc realloc
  134. inline void* _kanjimalloc(size_t size) { return malloc(size); }
  135. inline void _kanjifree(void* ptr) { free(ptr); }
  136. inline void* _kanjirealloc(void* ptr, size_t size) { return realloc(ptr, size); }
  137. #endif // KANJI_MEMTRACE
  138. #endif // __KANJIMEMORY_H__