From 5b39dc76f1bc82f941d5c800ab9f34407a06b53a Mon Sep 17 00:00:00 2001 From: Igor Pavlov <87184205+ip7z@users.noreply.github.com> Date: Wed, 21 Jun 2023 00:00:00 +0000 Subject: 23.01 --- CPP/Common/NewHandler.cpp | 184 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 151 insertions(+), 33 deletions(-) (limited to 'CPP/Common/NewHandler.cpp') diff --git a/CPP/Common/NewHandler.cpp b/CPP/Common/NewHandler.cpp index 65ef41d..c95833e 100644 --- a/CPP/Common/NewHandler.cpp +++ b/CPP/Common/NewHandler.cpp @@ -10,21 +10,23 @@ #ifndef DEBUG_MEMORY_LEAK -#ifdef _7ZIP_REDEFINE_OPERATOR_NEW +#ifdef Z7_REDEFINE_OPERATOR_NEW /* void * my_new(size_t size) { // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + if (size == 0) + size = 1; void *p = ::malloc(size); - if (p == 0) + if (!p) throw CNewException(); return p; } void my_delete(void *p) throw() { - // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p); + // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p); ::free(p); } @@ -44,9 +46,21 @@ __cdecl #endif operator new(size_t size) { + /* by C++ specification: + if (size == 0), operator new(size) returns non_NULL pointer. + If (operator new(0) returns NULL), it's out of specification. + but some calling code can work correctly even in this case too. */ + // if (size == 0) return NULL; // for debug only. don't use it + + /* malloc(0) returns non_NULL in main compilers, as we need here. + But specification also allows malloc(0) to return NULL. + So we change (size=0) to (size=1) here to get real non_NULL pointer */ + if (size == 0) + size = 1; // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + // void *p = ::MyAlloc(size); // note: MyAlloc(0) returns NULL void *p = ::malloc(size); - if (p == 0) + if (!p) throw CNewException(); return p; } @@ -57,7 +71,8 @@ __cdecl #endif operator delete(void *p) throw() { - // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p); + // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p); + // MyFree(p); ::free(p); } @@ -69,8 +84,10 @@ __cdecl operator new[](size_t size) { // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + if (size == 0) + size = 1; void *p = ::malloc(size); - if (p == 0) + if (!p) throw CNewException(); return p; } @@ -81,7 +98,7 @@ __cdecl #endif operator delete[](void *p) throw() { - // if (p == 0) return; ::HeapFree(::GetProcessHeap(), 0, p); + // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p); ::free(p); } */ @@ -93,16 +110,43 @@ operator delete[](void *p) throw() #include // #pragma init_seg(lib) +/* const int kDebugSize = 1000000; static void *a[kDebugSize]; -static int index = 0; +static int g_index = 0; + +class CC +{ +public: + CC() + { + for (int i = 0; i < kDebugSize; i++) + a[i] = 0; + } + ~CC() + { + printf("\nDestructor: %d\n", numAllocs); + for (int i = 0; i < kDebugSize; i++) + if (a[i] != 0) + return; + } +} g_CC; +*/ +#ifdef _WIN32 static bool wasInit = false; static CRITICAL_SECTION cs; +#endif static int numAllocs = 0; -void * __cdecl operator new(size_t size) + +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new(size_t size) { + #ifdef _WIN32 if (!wasInit) { InitializeCriticalSection(&cs); @@ -114,52 +158,126 @@ void * __cdecl operator new(size_t size) int loc = numAllocs; void *p = HeapAlloc(GetProcessHeap(), 0, size); /* - if (index < kDebugSize) + if (g_index < kDebugSize) { - a[index] = p; - index++; + a[g_index] = p; + g_index++; } */ printf("Alloc %6d, size = %8u\n", loc, (unsigned)size); LeaveCriticalSection(&cs); - if (p == 0) + if (!p) throw CNewException(); return p; -} - -class CC -{ -public: - CC() - { - for (int i = 0; i < kDebugSize; i++) - a[i] = 0; - } - ~CC() + #else + numAllocs++; + int loc = numAllocs; + if (size == 0) + size = 1; + void *p = malloc(size); + /* + if (g_index < kDebugSize) { - printf("\nDestructor: %d\n", numAllocs); - for (int i = 0; i < kDebugSize; i++) - if (a[i] != 0) - return; + a[g_index] = p; + g_index++; } -} g_CC; - + */ + printf("Alloc %6d, size = %8u\n", loc, (unsigned)size); + if (!p) + throw CNewException(); + return p; + #endif +} -void __cdecl operator delete(void *p) +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw() { - if (p == 0) + if (!p) return; + #ifdef _WIN32 EnterCriticalSection(&cs); /* - for (int i = 0; i < index; i++) + for (int i = 0; i < g_index; i++) if (a[i] == p) a[i] = 0; */ HeapFree(GetProcessHeap(), 0, p); + if (numAllocs == 0) + numAllocs = numAllocs; // ERROR numAllocs--; + if (numAllocs == 0) + numAllocs = numAllocs; // OK: all objects were deleted printf("Free %d\n", numAllocs); LeaveCriticalSection(&cs); + #else + free(p); + numAllocs--; + printf("Free %d\n", numAllocs); + #endif +} + +/* +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new[](size_t size) +{ + printf("operator_new[] : "); + return operator new(size); +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p, size_t sz) throw(); + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p, size_t sz) throw() +{ + if (!p) + return; + printf("operator_delete_size : size=%d : ", (unsigned)sz); + operator delete(p); +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p) throw() +{ + if (!p) + return; + printf("operator_delete[] : "); + operator delete(p); +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p, size_t sz) throw(); + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p, size_t sz) throw() +{ + if (!p) + return; + printf("operator_delete_size[] : size=%d : ", (unsigned)sz); + operator delete(p); } +*/ #endif -- cgit v1.2.3-55-g6feb