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