From 748d7bf4b1cf1dede8d70d57b6080e3938f5a5bd Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 9 May 2006 00:02:37 +0000 Subject: [PATCH] - The game is now free of leaks up to the point just after the wads are loaded. - Fixed: Although TypeInfos are now deleted at exit, their FlatPointers or ActorInfo data was not freed. I chose not to use a destructor to handle this, because then it would no longer be a POD type that can be statically initialized. - Fixed: Aliases were not deleted at exit. - Fixed: FWadCollection did not free its hash tables, lump info, full names, or the list of open files when destroyed. SVN r85 (trunk) --- docs/rh-log.txt | 7 +++++ src/c_dispatch.cpp | 29 +++++++++++++++++--- src/dobject.cpp | 62 ++++++++++++++++++++++++++++++++++++------- src/dobject.h | 12 +++------ src/w_wad.cpp | 41 ++++++++++++++++++++++++++++ tools/lemon/lemon.c | 37 +++++++++++++------------- tools/re2c/actions.cc | 2 +- tools/re2c/dfa.cc | 2 +- zdoom.vcproj | 9 ------- 9 files changed, 151 insertions(+), 50 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 0c4b4e05b..f6a77c315 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -10,6 +10,13 @@ May 7, 2006 (Changes by Graf Zahl) a label, in addition to goto. May 6, 2006 +- The game is now free of leaks up to the point just after the wads are loaded. +- Fixed: Although TypeInfos are now deleted at exit, their FlatPointers or ActorInfo + data was not freed. I chose not to use a destructor to handle this, because then it + would no longer be a POD type that can be statically initialized. +- Fixed: Aliases were not deleted at exit. +- Fixed: FWadCollection did not free its hash tables, lump info, full names, or the + list of open files when destroyed. - Updated Italian strings that someone kindly e-mailed to me. - The CRT no longer detects any memory leaks when I run to the IWAD picker and quit. - Fixed: The memory used to hold the path to zdoom.wad/.pk3 was not freed if diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 8243cf56c..55e3acb88 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -64,8 +64,6 @@ static const char *KeyConfCommands[] = "setslot" }; - - static long ParseCommandLine (const char *args, int *argc, char **argv); CVAR (Bool, lookspring, true, CVAR_ARCHIVE); // Generate centerview when -mlook encountered? @@ -149,7 +147,32 @@ FActionMap ActionMaps[] = { 0xf01cb105, &Button_LookUp, "lookup" }, }; -#define NUM_ACTIONS (sizeof(ActionMaps)/sizeof(FActionMap)) +#define NUM_ACTIONS countof(ActionMaps) + +static struct AliasKiller +{ + ~AliasKiller() + { + // Scan the hash table for all aliases and delete them. + // Regular commands will be destroyed automatically. + for (size_t i = 0; i < countof(Commands); ++i) + { + FConsoleCommand *cmd = Commands[i]; + + while (cmd != NULL) + { + FConsoleCommand *next = cmd->m_Next; + if (cmd->IsAlias()) + { + delete cmd; + } + cmd = next; + } + } + } +} KillTheAliases; + + IMPLEMENT_CLASS (DWaitingCommand) diff --git a/src/dobject.cpp b/src/dobject.cpp index c7caa76a1..9d20c1a98 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -47,9 +47,9 @@ #include "r_state.h" #include "stats.h" -TypeInfo::DeletingArray TypeInfo::m_RuntimeActors; +TArray TypeInfo::m_RuntimeActors; TArray TypeInfo::m_Types (256); -unsigned int TypeInfo::TypeHash[256]; // Why can't I use TypeInfo::HASH_SIZE? +unsigned int TypeInfo::TypeHash[TypeInfo::HASH_SIZE]; // Why can't I use TypeInfo::HASH_SIZE? #if defined(_MSC_VER) || defined(__GNUC__) #include "autosegs.h" @@ -77,15 +77,60 @@ TypeInfo DObject::_StaticType(NULL, "DObject", NULL, sizeof(DObject)); static cycle_t StaleCycles; static int StaleCount; -TypeInfo::DeletingArray::~DeletingArray() +// A harmless non_NULL FlatPointer for classes without pointers. +static const size_t TheEnd = ~0; + +static struct TypeInfoDataFreeer { - for (unsigned int i = 0; i < Size(); ++i) + ~TypeInfoDataFreeer() { - if ((*this)[i] != NULL) + TArray uniqueFPs(64); + unsigned int i, j; + + for (i = 0; i < TypeInfo::m_Types.Size(); ++i) { - delete (*this)[i]; - (*this)[i] = NULL; + TypeInfo *type = TypeInfo::m_Types[i]; + if (type->FlatPointers != &TheEnd && type->FlatPointers != type->Pointers) + { + // FlatPointers are shared by many classes, so we must check for + // duplicates and only delete those that are unique. + for (j = 0; j < uniqueFPs.Size(); ++j) + { + if (type->FlatPointers == uniqueFPs[j]) + { + break; + } + } + if (j == uniqueFPs.Size()) + { + uniqueFPs.Push(const_cast(type->FlatPointers)); + } + } + // For runtime classes, this call will also delete the TypeInfo. + TypeInfo::StaticFreeData (type); } + for (i = 0; i < uniqueFPs.Size(); ++i) + { + delete[] uniqueFPs[i]; + } + } +} FreeTypeInfoData; + +void TypeInfo::StaticFreeData (TypeInfo *type) +{ + if (type->ActorInfo != NULL) + { + delete type->ActorInfo; + type->ActorInfo = NULL; + } + if (type->bRuntimeClass) + { + if (type->Name != NULL) + { + delete[] type->Name; + } + type->Name = NULL; + delete type; } } @@ -199,6 +244,7 @@ TypeInfo *TypeInfo::CreateDerivedClass (char *name, unsigned int size) type->RegisterType(); type->Meta = Meta; type->FlatPointers = NULL; + type->bRuntimeClass = true; // If this class has an actor info, then any classes derived from it // also need an actor info. @@ -233,8 +279,6 @@ TypeInfo *TypeInfo::CreateDerivedClass (char *name, unsigned int size) // to the same array as the super class's. void TypeInfo::BuildFlatPointers () { - static const size_t TheEnd = ~0; - if (FlatPointers != NULL) { // Already built: Do nothing. return; diff --git a/src/dobject.h b/src/dobject.h index bb426fbb1..4242d1c1f 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -133,6 +133,7 @@ private: struct TypeInfo { static void StaticInit (); + static void StaticFreeData (TypeInfo *type); const char *Name; TypeInfo *ParentType; @@ -142,6 +143,7 @@ struct TypeInfo FActorInfo *ActorInfo; unsigned int HashNext; unsigned short TypeIndex; + bool bRuntimeClass; // class was defined at run-time, not compile-time FMetaTable Meta; const size_t *FlatPointers; // object pointers defined by this class and all its superclasses; not initialized by default @@ -169,16 +171,8 @@ struct TypeInfo static const TypeInfo *FindType (const char *name); static const TypeInfo *IFindType (const char *name); - // The DeletingArray deletes all the TypeInfos it points to - // when it gets destroyed. - class DeletingArray : public TArray - { - public: - ~DeletingArray(); - }; - static TArray m_Types; - static DeletingArray m_RuntimeActors; + static TArray m_RuntimeActors; enum { HASH_SIZE = 256 }; static unsigned int TypeHash[HASH_SIZE]; diff --git a/src/w_wad.cpp b/src/w_wad.cpp index d61db895e..2d77470fd 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -166,6 +166,47 @@ FWadCollection::FWadCollection () FWadCollection::~FWadCollection () { + if (FirstLumpIndex != NULL) + { + delete[] FirstLumpIndex; + FirstLumpIndex = NULL; + } + if (NextLumpIndex != NULL) + { + delete[] NextLumpIndex; + NextLumpIndex = NULL; + } + if (FirstLumpIndex_FullName != NULL) + { + delete[] FirstLumpIndex_FullName; + FirstLumpIndex_FullName = NULL; + } + if (NextLumpIndex_FullName != NULL) + { + delete[] NextLumpIndex_FullName; + NextLumpIndex_FullName = NULL; + } + if (LumpInfo != NULL) + { + for (DWORD i = 0; i < NumLumps; ++i) + { + if (LumpInfo[i].fullname != NULL) + { + delete[] LumpInfo[i].fullname; + } + } + delete[] LumpInfo; + LumpInfo = NULL; + } + if (Wads != NULL) + { + for (DWORD i = 0; i < NumWads; ++i) + { + delete Wads[i]; + } + delete[] Wads; + Wads = NULL; + } } //========================================================================== diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index e1eca6538..3f2901930 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -1262,9 +1262,9 @@ int max; void ErrorMsg(const char *filename, int lineno, const char *format, ...){ char errmsg[ERRMSGSIZE]; char prefix[PREFIXLIMIT+10]; - int errmsgsize; - int prefixsize; - int availablewidth; + size_t errmsgsize; + size_t prefixsize; + size_t availablewidth; va_list ap; int end, restart, base; @@ -1494,7 +1494,7 @@ char **argv; /* ** Return a pointer to the next structure in the linked list. */ -#define NEXT(A) (*(char**)(((unsigned long)A)+offset)) +#define NEXT(A) (*(char**)(((size_t)A)+offset)) /* ** Inputs: @@ -1568,11 +1568,11 @@ char *list; char **next; int (*cmp)(); { - unsigned long offset; + size_t offset; char *ep; char *set[LISTSIZE]; int i; - offset = (unsigned long)next - (unsigned long)list; + offset = (size_t)next - (size_t)list; for(i=0; insymbol; i++){ sp = lemp->symbols[i]; - len = strlen(sp->name); + len = (int)strlen(sp->name); if( len>maxlen ) maxlen = len; } ncolumns = 76/(maxlen+5); @@ -3037,8 +3038,8 @@ struct lemon *lemp; */ PRIVATE char *append_str(char *zText, int n, int p1, int p2){ static char *z = 0; - static int alloced = 0; - static int used = 0; + static size_t alloced = 0; + static size_t used = 0; int c; char zInt[40]; @@ -3051,7 +3052,7 @@ PRIVATE char *append_str(char *zText, int n, int p1, int p2){ used += n; assert( used>=0 ); } - n = strlen(zText); + n = (int)strlen(zText); } if( n+sizeof(zInt)*2+used >= alloced ){ alloced = n + sizeof(zInt)*2 + used + 200; @@ -3207,13 +3208,13 @@ int mhflag; /* True if generating makeheaders output */ for(i=0; ivartype ){ - maxdtlength = strlen(lemp->vartype); + maxdtlength = (int)strlen(lemp->vartype); } for(i=0; insymbol; i++){ int len; struct symbol *sp = lemp->symbols[i]; if( sp->datatype==0 ) continue; - len = strlen(sp->datatype); + len = (int)strlen(sp->datatype); if( len>maxdtlength ) maxdtlength = len; } stddt = (char*)malloc( maxdtlength*2 + 1 ); @@ -3410,7 +3411,7 @@ int mhflag; /* Output in makeheaders format if true */ name = lemp->name ? lemp->name : "Parse"; if( lemp->arg && lemp->arg[0] ){ int i; - i = strlen(lemp->arg); + i = (int)strlen(lemp->arg); while( i>=1 && isspace(lemp->arg[i-1]) ) i--; while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++; diff --git a/tools/re2c/actions.cc b/tools/re2c/actions.cc index beec2890f..7a596396d 100644 --- a/tools/re2c/actions.cc +++ b/tools/re2c/actions.cc @@ -27,7 +27,7 @@ void showIns(std::ostream &o, const Ins &i, const Ins &base){ case CHAR: { o << "match "; for(const Ins *j = &(&i)[1]; j < (Ins*) i.i.link; ++j) - prtCh(o, j->c.value); + prtCh(o, (const uchar)j->c.value); break; } case GOTO: o << "goto " << ((Ins*) i.i.link - &base); diff --git a/tools/re2c/dfa.cc b/tools/re2c/dfa.cc index b3e1e618a..660db6026 100644 --- a/tools/re2c/dfa.cc +++ b/tools/re2c/dfa.cc @@ -127,7 +127,7 @@ DFA::DFA(Ins *ins, uint ni, uint lb, uint ub, Char *rep) if(i->i.tag == CHAR){ for(Ins *j = i + 1; j < (Ins*) i->i.link; ++j){ if(!(j->c.link = goTo[j->c.value - lb].to)) - goTo[nGoTos++].ch = j->c.value; + goTo[nGoTos++].ch = (Char)j->c.value; goTo[j->c.value - lb].to = j; } } else if(i->i.tag == TERM){ diff --git a/zdoom.vcproj b/zdoom.vcproj index 1ff1ae45a..c6032e954 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -3994,9 +3994,6 @@ - - @@ -4015,15 +4012,9 @@ - - - -