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
69 #if defined(_MSC_VER) && _MSC_VER == 1600
70 // vs2010 has no throw() by default ?
71 #pragma warning(push)
72 #pragma warning(disable : 4986) // 'operator delete': exception specification does not match previous declaration
73 #endif
74
75 void
76 #ifdef _MSC_VER
77 __cdecl
78 #endif
operator delete(void * p)79 operator delete(void *p) throw()
80 {
81 // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
82 // MyFree(p);
83 ::free(p);
84 }
85
86 /* we define operator delete(void *p, size_t n) because
87 vs2022 compiler uses delete(void *p, size_t n), and
88 we want to mix files from different compilers:
89 - old vc6 linker
90 - old vc6 complier
91 - new vs2022 complier
92 */
93 void
94 #ifdef _MSC_VER
95 __cdecl
96 #endif
operator delete(void * p,size_t n)97 operator delete(void *p, size_t n) throw()
98 {
99 UNUSED_VAR(n)
100 ::free(p);
101 }
102
103 #if defined(_MSC_VER) && _MSC_VER == 1600
104 #pragma warning(pop)
105 #endif
106
107 /*
108 void *
109 #ifdef _MSC_VER
110 __cdecl
111 #endif
112 operator new[](size_t size)
113 {
114 // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
115 if (size == 0)
116 size = 1;
117 void *p = ::malloc(size);
118 if (!p)
119 throw CNewException();
120 return p;
121 }
122
123 void
124 #ifdef _MSC_VER
125 __cdecl
126 #endif
127 operator delete[](void *p) throw()
128 {
129 // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
130 ::free(p);
131 }
132 */
133
134 #endif
135
136 #else
137
138 #include <stdio.h>
139
140 // #pragma init_seg(lib)
141 /*
142 const int kDebugSize = 1000000;
143 static void *a[kDebugSize];
144 static int g_index = 0;
145
146 class CC
147 {
148 public:
149 CC()
150 {
151 for (int i = 0; i < kDebugSize; i++)
152 a[i] = 0;
153 }
154 ~CC()
155 {
156 printf("\nDestructor: %d\n", numAllocs);
157 for (int i = 0; i < kDebugSize; i++)
158 if (a[i] != 0)
159 return;
160 }
161 } g_CC;
162 */
163
164 #ifdef _WIN32
165 static bool wasInit = false;
166 static CRITICAL_SECTION cs;
167 #endif
168
169 static int numAllocs = 0;
170
171 void *
172 #ifdef _MSC_VER
173 __cdecl
174 #endif
operator new(size_t size)175 operator new(size_t size)
176 {
177 #ifdef _WIN32
178 if (!wasInit)
179 {
180 InitializeCriticalSection(&cs);
181 wasInit = true;
182 }
183 EnterCriticalSection(&cs);
184
185 numAllocs++;
186 int loc = numAllocs;
187 void *p = HeapAlloc(GetProcessHeap(), 0, size);
188 /*
189 if (g_index < kDebugSize)
190 {
191 a[g_index] = p;
192 g_index++;
193 }
194 */
195 printf("Alloc %6d, size = %8u\n", loc, (unsigned)size);
196 LeaveCriticalSection(&cs);
197 if (!p)
198 throw CNewException();
199 return p;
200 #else
201 numAllocs++;
202 int loc = numAllocs;
203 if (size == 0)
204 size = 1;
205 void *p = malloc(size);
206 /*
207 if (g_index < kDebugSize)
208 {
209 a[g_index] = p;
210 g_index++;
211 }
212 */
213 printf("Alloc %6d, size = %8u\n", loc, (unsigned)size);
214 if (!p)
215 throw CNewException();
216 return p;
217 #endif
218 }
219
220 void
221 #ifdef _MSC_VER
222 __cdecl
223 #endif
operator delete(void * p)224 operator delete(void *p) throw()
225 {
226 if (!p)
227 return;
228 #ifdef _WIN32
229 EnterCriticalSection(&cs);
230 /*
231 for (int i = 0; i < g_index; i++)
232 if (a[i] == p)
233 a[i] = 0;
234 */
235 HeapFree(GetProcessHeap(), 0, p);
236 // if (numAllocs == 0) numAllocs = numAllocs; // ERROR
237 numAllocs--;
238 // if (numAllocs == 0) numAllocs = numAllocs; // OK: all objects were deleted
239 printf("Free %d\n", numAllocs);
240 LeaveCriticalSection(&cs);
241 #else
242 free(p);
243 numAllocs--;
244 printf("Free %d\n", numAllocs);
245 #endif
246 }
247
248 void
249 #ifdef _MSC_VER
250 __cdecl
251 #endif
252 operator delete(void *p, size_t n) throw();
253 void
254 #ifdef _MSC_VER
255 __cdecl
256 #endif
operator delete(void * p,size_t n)257 operator delete(void *p, size_t n) throw()
258 {
259 UNUSED_VAR(n)
260 printf("delete_WITH_SIZE=%u, ptr = %p\n", (unsigned)n, p);
261 operator delete(p);
262 }
263
264 /*
265 void *
266 #ifdef _MSC_VER
267 __cdecl
268 #endif
269 operator new[](size_t size)
270 {
271 printf("operator_new[] : ");
272 return operator new(size);
273 }
274
275 void
276 #ifdef _MSC_VER
277 __cdecl
278 #endif
279 operator delete(void *p, size_t sz) throw();
280
281 void
282 #ifdef _MSC_VER
283 __cdecl
284 #endif
285 operator delete(void *p, size_t sz) throw()
286 {
287 if (!p)
288 return;
289 printf("operator_delete_size : size=%d : ", (unsigned)sz);
290 operator delete(p);
291 }
292
293 void
294 #ifdef _MSC_VER
295 __cdecl
296 #endif
297 operator delete[](void *p) throw()
298 {
299 if (!p)
300 return;
301 printf("operator_delete[] : ");
302 operator delete(p);
303 }
304
305 void
306 #ifdef _MSC_VER
307 __cdecl
308 #endif
309 operator delete[](void *p, size_t sz) throw();
310
311 void
312 #ifdef _MSC_VER
313 __cdecl
314 #endif
315 operator delete[](void *p, size_t sz) throw()
316 {
317 if (!p)
318 return;
319 printf("operator_delete_size[] : size=%d : ", (unsigned)sz);
320 operator delete(p);
321 }
322 */
323
324 #endif
325
326 /*
327 int MemErrorVC(size_t)
328 {
329 throw CNewException();
330 // return 1;
331 }
332 CNewHandlerSetter::CNewHandlerSetter()
333 {
334 // MemErrorOldVCFunction = _set_new_handler(MemErrorVC);
335 }
336 CNewHandlerSetter::~CNewHandlerSetter()
337 {
338 // _set_new_handler(MemErrorOldVCFunction);
339 }
340 */
341