diff --git a/src/libs/tgf/memmanager.cpp b/src/libs/tgf/memmanager.cpp index ab75e8b9b..8a8df0efc 100644 --- a/src/libs/tgf/memmanager.cpp +++ b/src/libs/tgf/memmanager.cpp @@ -87,6 +87,10 @@ void _tgf_win_free(void * b) GfMemoryManagerFree(b, GF_MM_ALLOCTYPE_MALLOC); } +void _tgf_win_accept(void * b) +{ + GfMemoryManagerAccept(b, GF_MM_ALLOCTYPE_MALLOC); +} void * _tgf_win_calloc(size_t num, size_t size) { @@ -213,7 +217,7 @@ void* GfMemoryManagerAlloc (size_t size, unsigned int Type, void* RetAddr) // b: (void*) official pointer to the new data block // Hunting memory leaks ... -#define IDTOSTOP 6486 // ID of block you are looking for +#define IDTOSTOP 7815 // ID of block you are looking for if (ID == IDTOSTOP) { @@ -243,7 +247,7 @@ void* GfMemoryManagerAlloc (size_t size, unsigned int Type, void* RetAddr) // // -// Override the global delete operator +// Release memory // void GfMemoryManagerFree (void *b, unsigned int type) { @@ -290,6 +294,52 @@ void GfMemoryManagerFree (void *b, unsigned int type) } // +// +// Accept memory +// +void GfMemoryManagerAccept (void *b, unsigned int type) +{ + if (b == NULL) + return; + + if (GfMemoryManagerRunning()) + { + // Get start of data block ... + int* s = (int*) b; + tDSMMLinkBlock* c = (tDSMMLinkBlock*) --s; + c = --c; + // ... Get start of data block + + // Now we have here + // b: (void*) official pointer to data block + // s: (in*) to size of allocated block + // c: (tDSMMLinkBlock*) to the current linked list data block + // n: (tDSMMLinkBlock*) to the next linked list data block + // p: (tDSMMLinkBlock*) to the previous linked list data block + + if (c->Type != type) + { + if (c->Mark = MM_MARKER) + fprintf(stderr,"operator delete called with data of wrong type\n"); + else + fprintf(stderr,"operator delete wrong data\n"); + } + else + { + tDSMMLinkBlock* n = c->Next; + tDSMMLinkBlock* p = c->Prev; + if (c->Mark = MM_MARKER) + { + fprintf(stderr,"accept block %d\n",c->ID); + p->Next = n; + if (n != NULL) + n->Prev = p; + } + } + } +} +// + // // Setup data of memory manager // diff --git a/src/libs/tgf/memmanager.h b/src/libs/tgf/memmanager.h index 7cfa7c97d..b4815c858 100644 --- a/src/libs/tgf/memmanager.h +++ b/src/libs/tgf/memmanager.h @@ -54,6 +54,7 @@ TGF_API void GfMemoryManagerSetup(int AddedSpace); // Memory manager worker functions void* GfMemoryManagerAlloc(size_t size, unsigned int type, void* RetAddr); void GfMemoryManagerFree(void* b, unsigned int type); +void GfMemoryManagerAccept(void* b, unsigned int type); // // Block to link allocated memory blocks in a diff --git a/src/libs/tgf/tgf.h b/src/libs/tgf/tgf.h index 77871fc70..5f37a5674 100644 --- a/src/libs/tgf/tgf.h +++ b/src/libs/tgf/tgf.h @@ -224,6 +224,7 @@ TGF_API void GfPoolMove(tMemoryPool* oldPool, tMemoryPool* newPool); #define calloc _tgf_win_calloc #define realloc _tgf_win_realloc #define free _tgf_win_free +#define accept _tgf_win_accept #ifdef strdup #undef strdup #endif @@ -233,6 +234,7 @@ TGF_API void * _tgf_win_malloc(size_t size); TGF_API void * _tgf_win_calloc(size_t num, size_t size); TGF_API void * _tgf_win_realloc(void * memblock, size_t size); TGF_API void _tgf_win_free(void * memblock); +TGF_API void _tgf_win_accept(void * memblock); TGF_API char * _tgf_win_strdup(const char * str); #endif // WIN32 diff --git a/src/libs/tgfclient/gui.cpp b/src/libs/tgfclient/gui.cpp index ddfe715d8..79a48429c 100644 --- a/src/libs/tgfclient/gui.cpp +++ b/src/libs/tgfclient/gui.cpp @@ -705,6 +705,8 @@ GfuiScreenCreate(float *bgColor, screen->keyAutoRepeat = 1; // Default key auto-repeat on. + RegisterScreens(screen); + return (void*)screen; } diff --git a/src/libs/tgfclient/tgfclient.cpp b/src/libs/tgfclient/tgfclient.cpp index 68fe99d5e..7e65a081a 100644 --- a/src/libs/tgfclient/tgfclient.cpp +++ b/src/libs/tgfclient/tgfclient.cpp @@ -18,6 +18,56 @@ #include "gui.h" +// Avoid memory leaks ... +int NumberOfScreens = -1; +tGfuiScreen* OwnerOfScreens[MAXSCREENS]; + +void RegisterScreens(void* screen) +{ + if (++NumberOfScreens < MAXSCREENS) + OwnerOfScreens[NumberOfScreens] = (tGfuiScreen*) screen; + else + GfLogInfo("NumberOfScreens: %d > MAXSCREENS\n", NumberOfScreens); +} + +void FreeScreens() +{ + for (int I = 0; I <= NumberOfScreens; I++) + { + tGfuiScreen* screen = OwnerOfScreens[I]; + if (screen) + { + tGfuiObject* object = screen->objects; + while (object) + { + tGfuiObject* release = object; + object = object->next; + if (object == release) + object = NULL; + if (object == screen->objects) + object = NULL; + gfuiReleaseObject(release); + } + + tGfuiKey* key = screen->userKeys; + while (key) + { + tGfuiKey* relkey = key; + key = key->next; + if (key == relkey) + key = NULL; + if (key == screen->userKeys) + key = NULL; + free(relkey->name); + free(relkey->descr); + free(relkey); + } + + free(screen); + } + } +} +// ... Avoid memory leaks void GfuiInit(void) { @@ -27,6 +77,8 @@ void GfuiInit(void) void GfuiShutdown(void) { gfuiShutdown(); + + FreeScreens(); GfScrShutdown(); } diff --git a/src/libs/tgfclient/tgfclient.h b/src/libs/tgfclient/tgfclient.h index 7e1e96b14..c2126b9ed 100644 --- a/src/libs/tgfclient/tgfclient.h +++ b/src/libs/tgfclient/tgfclient.h @@ -795,6 +795,11 @@ inline GfuiApplication& GfuiApp() return dynamic_cast(GfApplication::self()); } +// TODO: Use dynamic array for OwnerOfScreens +#define MAXSCREENS 100 +void RegisterScreens(void* screen); +void FreeScreens(); + #endif /* __TGFCLIENT__H__ */