/** ****************************************************************************** @file /common/mm.h @brief Memory manager/ helpers/ debug functions Pouzivanim tehto rutin snadno odhalite, jestli program spravne alokuje [pocet alokaci = dealokaci] Pripadne rozsireni i na jine debug informace (adresy alokovane, poradi, mnozstvi, prumerne velikosti,...) Pouzivejte u velkych dat, u trid neni potreba =>nepouzivejte tridy na velka data(jako class pixel,..) K8_MM_DEBUG - ladeni pameti K8_MM_NEWDEBUG - ladeni new/delete, narocne K8_MM_DADEBUG - ladeni DA, jeste narocnejsi MEMDBG_FILE - soubor s vypisem K8_MM_MALLOCCHECK - kontrola alokace pameti @author Vajicek @version 0.1 ******************************************************************************/ #ifndef MM_H #define MM_H #include #include #include "common/Log.h" /// soubor #define MEMDBG_FILE "mem.dbg" //makra pro de/alokaci pameti #ifdef K8_MM_DEBUG //logovani adres, zdrojaku a cisel radku #define KMemAlloc(a) DebugMemAlloc3(a,__LINE__,__FILE__) #define KMemRealloc(a,b) DebugMemRealloc3(a,b,__LINE__,__FILE__) #define KMemFree(a) {if (a==NULL) { GLOBALLOG("\nWar: Free(NULL) v %s na %i",__FILE__,__LINE__);} DebugMemFree3(a);a=NULL;} //logovani adres // #define KMemAlloc DebugMemAlloc2 // #define KMemRealloc DebugMemRealloc2 // #define KMemFree(a) {DebugMemFree2(a);a=NULL;} //logovani da #ifdef K8_MM_DADEBUG #define KDAnew(a) DebugMemDAnew(a) #define KDAdelete(a) DebugMemDAdelete(a) #else #define KDAnew(a) #define KDAdelete(a) #endif //logovani new #ifdef K8_MM_NEWDEBUG #ifdef __cplusplus void* operator new(size_t s); void operator delete(void* p); #endif #endif #else //kontrola uspesneho naalokovani #ifdef K8_MM_MALLOCCHECK #define KMemAlloc(a) CheckedMemAlloc(a) #define KMemRealloc(a,b) CheckedMemRealloc(a,b) #ifdef __cplusplus void* operator new(size_t s); #endif //nativni #else #define KMemAlloc malloc #define KMemRealloc realloc #endif #define KMemFree free #define KDAnew(a) #define KDAdelete(a) #endif //vypis #define KDumpAllocMem DumpAllocMem2 #ifdef __cplusplus extern "C" { #endif extern void* DebugMemAlloc(size_t size); extern void* DebugMemRealloc(void *,size_t size); extern void DebugMemFree(void*); extern void* DebugMemAlloc2(size_t size); extern void* DebugMemRealloc2(void *,size_t size); extern void DebugMemFree2(void*); extern void DumpAllocMem(); extern void* DebugMemAlloc3(size_t size, int line, char* file); extern void* DebugMemRealloc3(void* mem,size_t size,int line, char* file); extern void DebugMemFree3(void* mem); extern void DumpAllocMem2(); extern void DebugMemDAnew(void * mem); extern void DebugMemDAdelete(void * mem); extern void* CheckedMemAlloc(size_t size); extern void* CheckedMemRealloc(void *mem, size_t size); #ifdef __cplusplus } #endif #ifdef __cplusplus //spolecny predek vsech trid pri debugovani class DebugClassHelper{ public: #ifdef K8_MM_DEBUG /**alokator pro vsechny tridy*/ void* operator new(size_t s); /**dealokator pro vsechny tridy*/ void operator delete(void* p); #endif }; #endif /** Sufixy vsech trid CLSDBG1 pro tridy, ktere nejsou nici potomky, CLSDBG2 pro odvozene tridy example: class trida CLSDBG1{ }; //misto class trida{ class trida2 CLSDBG2 public trida{ }; //misto class trida2: public trida{ */ #ifdef K8_MM_DEBUG #define CLSDBG1 :public DebugClassHelper #define CLSDBG2 :public DebugClassHelper, #define CLSDBG3 :public virtual DebugClassHelper #define CLSDBG4 :public virtual DebugClassHelper, #else #define CLSDBG1 #define CLSDBG2 : #define CLSDBG3 #define CLSDBG4 : #endif /** "Inteligentni" realokace poli. Realokuje(naoalokuej, zkopiruje, uvolni) pamet pro pole objektu velkych unit_size, kterych je new_count z pole ktere bylo velke old_count. Prebytky se ztrati. Ve zkutecnosti oproto beznemu reallocku alokuje jen tehdy, kdyz je prekrocena hranice mocniny dvou a to na dalsi mocninu dvou vyssi nez new_count. Hodi se u poli, kde neni jasna ani priblizna velikost. Plytva pameti. Az dvakrat vic. @param mem Puvodni pamet. @param unit_size Velikost jednotky pole v bytech. @param new_count Nova velikost pole v jednotkach. @param old_count Stara velikost pole v jednotkach. @return Vrati nove naalokovanou pamet. */ extern void* KExtArrayRealloc(void* mem, int unit_size, int new_count, int old_count); /** Realokuje pamet na presnou velikost. Pouziva se k uvolneni prebytecne pameti naalokovanim presne velikosti a prekopirovanim. */ extern void* KExtArrayAlign(void* mem, int unit_size,int old_count); /// Retezce, Alokuje + Inicializuje + Vrati, Uvolnuje //@{ extern char* KInitString(char* str); extern void KReleaseString(char* str); extern wchar_t* KInitWString(char* str); extern wchar_t* KInitWString(wchar_t* str); extern void KReleaseWString(wchar_t* str); //@} /** Inteligentni ukazatel. Pouziva se jako predek objektu, ktere mohou by zruseny na vice mistech. Pocita reference, veskere odkazy, ktere se drzi v dat strukturach se musi registrovat getRef a odregistrovat ungetRef(). Hodi se napriklad, kdyz se nevi, kdyz se nevi kdy by se objekt mohl zrusit. */ class TRefCounter{ private: int iRefs; public: /** Konstruktor. Inicializuje pocet referenci na 1. */ TRefCounter(); /** Registruje referenci. Inkrementuje pocitado referenci. */ TRefCounter* getRef(); /** Odregistruje referenci. Dekrementuje pocitadlo referenci o 1. */ void ungetRef(); /** Pocet referenci. @return Pocet referenci. */ int refCount(); /** Destruktor. */ virtual ~TRefCounter(); }; #endif //MM_H /*****************************************************************************/