1 // NewHandler.cpp
2 
3 #include "StdAfx.h"
4 
5 #include <stdlib.h>
6 
7 #include "NewHandler.h"
8 
9 // #define DEBUG_MEMORY_LEAK
10 
11 #ifndef DEBUG_MEMORY_LEAK
12 
13 #ifdef Z7_REDEFINE_OPERATOR_NEW
14 
15 /*
16 void * my_new(size_t size)
17 {
18   // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
19   if (size == 0)
20     size = 1;
21   void *p = ::malloc(size);
22   if (!p)
23     throw CNewException();
24   return p;
25 }
26 
27 void my_delete(void *p) throw()
28 {
29   // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
30   ::free(p);
31 }
32 
33 void * my_Realloc(void *p, size_t newSize, size_t oldSize)
34 {
35   void *newBuf = my_new(newSize);
36   if (oldSize != 0)
37     memcpy(newBuf, p, oldSize);
38   my_delete(p);
39   return newBuf;
40 }
41 */
42 
43 void *
44 #ifdef _MSC_VER
45 __cdecl
46 #endif
operator new(size_t size)47 operator new(size_t size)
48 {
49   /* by C++ specification:
50        if (size == 0), operator new(size) returns non_NULL pointer.
51      If (operator new(0) returns NULL), it's out of specification.
52        but some calling code can work correctly even in this case too. */
53   // if (size == 0) return NULL; // for debug only. don't use it
54 
55   /* malloc(0) returns non_NULL in main compilers, as we need here.
56      But specification also allows malloc(0) to return NULL.
57      So we change (size=0) to (size=1) here to get real non_NULL pointer */
58   if (size == 0)
59     size = 1;
60   // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
61   // void *p = ::MyAlloc(size);  // note: MyAlloc(0) returns NULL
62   void *p = ::malloc(size);
63   if (!p)
64     throw CNewException();
65   return p;
66 }
67 
68 void
69 #ifdef _MSC_VER
70 __cdecl
71 #endif
operator delete(void *p)72 operator delete(void *p) throw()
73 {
74   // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
75   // MyFree(p);
76   ::free(p);
77 }
78 
79 /*
80 void *
81 #ifdef _MSC_VER
82 __cdecl
83 #endif
84 operator new[](size_t size)
85 {
86   // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
87   if (size == 0)
88     size = 1;
89   void *p = ::malloc(size);
90   if (!p)
91     throw CNewException();
92   return p;
93 }
94 
95 void
96 #ifdef _MSC_VER
97 __cdecl
98 #endif
99 operator delete[](void *p) throw()
100 {
101   // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
102   ::free(p);
103 }
104 */
105 
106 #endif
107 
108 #else
109 
110 #include <stdio.h>
111 
112 // #pragma init_seg(lib)
113 /*
114 const int kDebugSize = 1000000;
115 static void *a[kDebugSize];
116 static int g_index = 0;
117 
118 class CC
119 {
120 public:
121   CC()
122   {
123     for (int i = 0; i < kDebugSize; i++)
124       a[i] = 0;
125   }
126   ~CC()
127   {
128     printf("\nDestructor: %d\n", numAllocs);
129     for (int i = 0; i < kDebugSize; i++)
130       if (a[i] != 0)
131         return;
132   }
133 } g_CC;
134 */
135 
136 #ifdef _WIN32
137 static bool wasInit = false;
138 static CRITICAL_SECTION cs;
139 #endif
140 
141 static int numAllocs = 0;
142 
143 void *
144 #ifdef _MSC_VER
145 __cdecl
146 #endif
operator new(size_t size)147 operator new(size_t size)
148 {
149  #ifdef _WIN32
150   if (!wasInit)
151   {
152     InitializeCriticalSection(&cs);
153     wasInit = true;
154   }
155   EnterCriticalSection(&cs);
156 
157   numAllocs++;
158   int loc = numAllocs;
159   void *p = HeapAlloc(GetProcessHeap(), 0, size);
160   /*
161   if (g_index < kDebugSize)
162   {
163     a[g_index] = p;
164     g_index++;
165   }
166   */
167   printf("Alloc %6d, size = %8u\n", loc, (unsigned)size);
168   LeaveCriticalSection(&cs);
169   if (!p)
170     throw CNewException();
171   return p;
172  #else
173   numAllocs++;
174   int loc = numAllocs;
175   if (size == 0)
176     size = 1;
177   void *p = malloc(size);
178   /*
179   if (g_index < kDebugSize)
180   {
181     a[g_index] = p;
182     g_index++;
183   }
184   */
185   printf("Alloc %6d, size = %8u\n", loc, (unsigned)size);
186   if (!p)
187     throw CNewException();
188   return p;
189  #endif
190 }
191 
192 void
193 #ifdef _MSC_VER
194 __cdecl
195 #endif
operator delete(void *p)196 operator delete(void *p) throw()
197 {
198   if (!p)
199     return;
200  #ifdef _WIN32
201   EnterCriticalSection(&cs);
202   /*
203   for (int i = 0; i < g_index; i++)
204     if (a[i] == p)
205       a[i] = 0;
206   */
207   HeapFree(GetProcessHeap(), 0, p);
208   if (numAllocs == 0)
209     numAllocs = numAllocs; // ERROR
210   numAllocs--;
211   if (numAllocs == 0)
212     numAllocs = numAllocs; // OK: all objects were deleted
213   printf("Free %d\n", numAllocs);
214   LeaveCriticalSection(&cs);
215  #else
216   free(p);
217   numAllocs--;
218   printf("Free %d\n", numAllocs);
219  #endif
220 }
221 
222 /*
223 void *
224 #ifdef _MSC_VER
225 __cdecl
226 #endif
227 operator new[](size_t size)
228 {
229   printf("operator_new[] : ");
230   return operator new(size);
231 }
232 
233 void
234 #ifdef _MSC_VER
235 __cdecl
236 #endif
237 operator delete(void *p, size_t sz) throw();
238 
239 void
240 #ifdef _MSC_VER
241 __cdecl
242 #endif
243 operator delete(void *p, size_t sz) throw()
244 {
245   if (!p)
246     return;
247   printf("operator_delete_size : size=%d  : ", (unsigned)sz);
248   operator delete(p);
249 }
250 
251 void
252 #ifdef _MSC_VER
253 __cdecl
254 #endif
255 operator delete[](void *p) throw()
256 {
257   if (!p)
258     return;
259   printf("operator_delete[] : ");
260   operator delete(p);
261 }
262 
263 void
264 #ifdef _MSC_VER
265 __cdecl
266 #endif
267 operator delete[](void *p, size_t sz) throw();
268 
269 void
270 #ifdef _MSC_VER
271 __cdecl
272 #endif
273 operator delete[](void *p, size_t sz) throw()
274 {
275   if (!p)
276     return;
277   printf("operator_delete_size[] : size=%d  : ", (unsigned)sz);
278   operator delete(p);
279 }
280 */
281 
282 #endif
283 
284 /*
285 int MemErrorVC(size_t)
286 {
287   throw CNewException();
288   // return 1;
289 }
290 CNewHandlerSetter::CNewHandlerSetter()
291 {
292   // MemErrorOldVCFunction = _set_new_handler(MemErrorVC);
293 }
294 CNewHandlerSetter::~CNewHandlerSetter()
295 {
296   // _set_new_handler(MemErrorOldVCFunction);
297 }
298 */
299