diff --git a/docs/rh-log.txt b/docs/rh-log.txt index a39d02a22..a131ae2c4 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,20 @@ May 3, 2006 +- Removed generational garbage collection from the string pool because it didn't + actually work. +- Turned the list of TabCommands into a TArray because I saw lots of console + commands in the memory leak report at exit. Then I realized those were actually + key bindings, so I changed the Bindings and DoubleBindings arrays into FString + arrays. +- Fixed: FStringCVar was missing a destructor. +- Added TArray::Insert(). +- Fixed: TArray::Delete() used memmove(). +- Renamed Malloc(), Realloc(), and Calloc() to M_Malloc(), M_Realloc(), and + M_Calloc() so that the debug versions can be defined as macros. +- Enabled the CRT's memory leak detection in WinMain(). +- Moved contents of PO_DeInit() into P_FreeLevelData(). +- Removed "PolyBlockMap = NULL;" from P_SetupLevel(), because the P_FreeLevelData() + call it makes next does the exact same thing, but also freeing it if needed. +- Fixed: Unneeded memcpy in UnpackUserCmd() when ucmd and basis are the same - Removed -bpal parameter. Blood's blood.pal is loaded from blood.rff, and its tiles are loaded from the same directory. - RFF files now load their entire directories into the lumplist. diff --git a/src/c_bind.cpp b/src/c_bind.cpp index c2fad65f2..1419f7e20 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -244,9 +244,8 @@ const char *KeyNames[NUM_KEYS] = "mwheelup", "mwheeldown", // the mouse wheel }; -static char *Bindings[NUM_KEYS]; - -static char *DoubleBindings[NUM_KEYS]; +static FString Bindings[NUM_KEYS]; +static FString DoubleBindings[NUM_KEYS]; static unsigned int DClickTime[NUM_KEYS]; static byte DClicked[(NUM_KEYS+7)/8]; @@ -343,7 +342,7 @@ CCMD (bind) } else { - ReplaceString (&Bindings[i], argv[2]); + Bindings[i] = argv[2]; } } else @@ -438,7 +437,7 @@ CCMD (doublebind) } else { - ReplaceString (&DoubleBindings[i], argv[2]); + DoubleBindings[i] = argv[2]; } } else @@ -455,7 +454,7 @@ CCMD (doublebind) CCMD (rebind) { - char **bindings; + FString *bindings; if (key == 0) { @@ -475,7 +474,7 @@ CCMD (rebind) if (argv.argc() > 1) { - ReplaceString (&bindings[key], argv[1]); + bindings[key] = argv[1]; } } @@ -603,7 +602,7 @@ BOOL C_DoKey (event_t *ev) void C_ArchiveBindings (FConfigFile *f, bool dodouble, const char *matchcmd) { - char **bindings; + FString *bindings; const char *name; int i; @@ -660,7 +659,7 @@ void C_DoBind (const char *key, const char *bind, bool dodouble) } if (keynum != 0) { - ReplaceString ((dodouble ? DoubleBindings : Bindings) + keynum, bind); + (dodouble ? DoubleBindings : Bindings)[keynum] = bind; } } @@ -734,5 +733,5 @@ void C_ChangeBinding (const char *str, int newone) char *C_GetBinding (int key) { - return (unsigned int)key < NUM_KEYS ? Bindings[key] : NULL; + return (unsigned int)key < NUM_KEYS ? Bindings[key].GetChars() : NULL; } diff --git a/src/c_console.cpp b/src/c_console.cpp index 189fbfc67..1d36888bd 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -574,7 +574,7 @@ void AddToConsole (int printlevel, const char *text) } if (size > worklen) { - work = (char *)Realloc (work, size); + work = (char *)M_Realloc (work, size); worklen = size; } if (work == NULL) @@ -1487,7 +1487,7 @@ static BOOL C_HandleKey (event_t *ev, byte *buffer, int len) // or there is nothing in the history list, // so add it to the history list. - History *temp = (History *)Malloc (sizeof(struct History) + buffer[0]); + History *temp = (History *)M_Malloc (sizeof(struct History) + buffer[0]); strcpy (temp->String, (char *)&buffer[2]); temp->Older = HistHead; @@ -1700,12 +1700,28 @@ void C_MidPrintBold (const char *msg) /****** Tab completion code ******/ -static struct TabData +struct TabData { int UseCount; - char *Name; -} *TabCommands = NULL; -static int NumTabCommands = 0; + FString Name; + + TabData() + : UseCount(0) + { + } + + TabData(const char *name) + : UseCount(1), Name(name) + { + } + + TabData(const TabData &other) + : UseCount(other.UseCount), Name(other.Name) + { + } +}; + +static TArray TabCommands; static int TabPos; // Last TabCommand tabbed to static int TabStart; // First char in CmdLine to use for tab completion static int TabSize; // Size of tab string @@ -1714,7 +1730,7 @@ static BOOL FindTabCommand (const char *name, int *stoppos, int len) { int i, cval = 1; - for (i = 0; i < NumTabCommands; i++) + for (i = 0; i < TabCommands.Size(); i++) { cval = strnicmp (TabCommands[i].Name, name, len); if (cval >= 0) @@ -1736,15 +1752,8 @@ void C_AddTabCommand (const char *name) } else { - NumTabCommands++; - TabCommands = (TabData *)Realloc (TabCommands, sizeof(struct TabData) * NumTabCommands); - if (pos < NumTabCommands - 1) - { - memmove (TabCommands + pos + 1, TabCommands + pos, - (NumTabCommands - pos - 1) * sizeof(struct TabData)); - } - TabCommands[pos].Name = copystring (name); - TabCommands[pos].UseCount = 1; + TabData tab(name); + TabCommands.Insert (pos, tab); } } @@ -1756,13 +1765,7 @@ void C_RemoveTabCommand (const char *name) { if (--TabCommands[pos].UseCount == 0) { - NumTabCommands--; - delete[] TabCommands[pos].Name; - if (pos < NumTabCommands - 1) - { - memmove (TabCommands + pos, TabCommands + pos + 1, - (NumTabCommands - pos - 1) * sizeof(struct TabData)); - } + TabCommands.Delete(pos); } } } @@ -1827,7 +1830,7 @@ static void C_TabComplete (bool goForward) } else { // Find the last matching tab, then go one past it. - while (++TabPos < NumTabCommands) + while (++TabPos < TabCommands.Size()) { if (FindDiffPoint (TabCommands[TabPos].Name, (char *)(CmdLine + TabStart)) < TabSize) { @@ -1842,7 +1845,7 @@ static void C_TabComplete (bool goForward) } } - if ((goForward && ++TabPos == NumTabCommands) || + if ((goForward && ++TabPos == TabCommands.Size()) || (!goForward && --TabPos < 0)) { TabbedLast = false; @@ -1878,7 +1881,7 @@ static bool C_TabCompleteList () nummatches = 0; maxwidth = 0; - for (i = TabPos; i < NumTabCommands; ++i) + for (i = TabPos; i < TabCommands.Size(); ++i) { if (FindDiffPoint (TabCommands[i].Name, (char *)(CmdLine + TabStart)) < TabSize) { diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index c23550700..b077218c5 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -783,6 +783,17 @@ FStringCVar::FStringCVar (const char *name, const char *def, DWORD flags, void ( DefaultValue = copystring (def); if (Flags & CVAR_ISDEFAULT) Value = copystring (def); + else + Value = NULL; +} + +FStringCVar::~FStringCVar () +{ + if (Value != NULL) + { + delete[] Value; + } + delete[] DefaultValue; } ECVarType FStringCVar::GetRealType () const diff --git a/src/c_cvars.h b/src/c_cvars.h index d406a9cd1..1c6d09c56 100644 --- a/src/c_cvars.h +++ b/src/c_cvars.h @@ -257,6 +257,7 @@ class FStringCVar : public FBaseCVar { public: FStringCVar (const char *name, const char *def, DWORD flags, void (*callback)(FStringCVar &)=NULL); + ~FStringCVar (); virtual ECVarType GetRealType () const; diff --git a/src/c_expr.cpp b/src/c_expr.cpp index b81e5dda8..337b4fced 100644 --- a/src/c_expr.cpp +++ b/src/c_expr.cpp @@ -306,7 +306,7 @@ static const char *IsNum (const char *str) static FStringProd *NewStringProd (const char *str) { - FStringProd *prod = (FStringProd *)Malloc (sizeof(FStringProd)+strlen(str)); + FStringProd *prod = (FStringProd *)M_Malloc (sizeof(FStringProd)+strlen(str)); prod->Type = PROD_String; strcpy (prod->Value, str); return prod; @@ -320,7 +320,7 @@ static FStringProd *NewStringProd (const char *str) static FStringProd *NewStringProd (size_t len) { - FStringProd *prod = (FStringProd *)Malloc (sizeof(FStringProd)+len); + FStringProd *prod = (FStringProd *)M_Malloc (sizeof(FStringProd)+len); prod->Type = PROD_String; prod->Value[0] = 0; return prod; @@ -334,7 +334,7 @@ static FStringProd *NewStringProd (size_t len) static FDoubleProd *NewDoubleProd (double val) { - FDoubleProd *prod = (FDoubleProd *)Malloc (sizeof(FDoubleProd)); + FDoubleProd *prod = (FDoubleProd *)M_Malloc (sizeof(FDoubleProd)); prod->Type = PROD_Double; prod->Value = val; return prod; diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index ac4cd1bf2..86838b027 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1942,7 +1942,7 @@ static int PatchStrings (int dummy) DPrintf ("[Strings]\n"); if (!holdstring) - holdstring = (char *)Malloc (maxstrlen); + holdstring = (char *)M_Malloc (maxstrlen); while ((result = GetLine()) == 1) { @@ -1952,7 +1952,7 @@ static int PatchStrings (int dummy) while (maxstrlen < strlen (holdstring) + strlen (Line2) + 8) { maxstrlen += 128; - holdstring = (char *)Realloc (holdstring, maxstrlen); + holdstring = (char *)M_Realloc (holdstring, maxstrlen); } strcat (holdstring, skipwhite (Line2)); stripwhite (holdstring); diff --git a/src/d_main.cpp b/src/d_main.cpp index 2473a758a..cde35b64f 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -662,7 +662,7 @@ CCMD (atexit) } for (int i = 1; i < argv.argc(); ++i) { - GameAtExit *record = (GameAtExit *)Malloc ( + GameAtExit *record = (GameAtExit *)M_Malloc ( sizeof(GameAtExit)+strlen(argv[i])); strcpy (record->Command, argv[i]); record->Next = ExitCmdList; @@ -1105,7 +1105,7 @@ void D_AddFile (const char *file) } file = f; } - wadlist_t *wad = (wadlist_t *)Malloc (sizeof(*wad) + strlen(file)); + wadlist_t *wad = (wadlist_t *)M_Malloc (sizeof(*wad) + strlen(file)); *wadtail = wad; wad->next = NULL; diff --git a/src/d_net.cpp b/src/d_net.cpp index e417f76a6..4cba433ea 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -178,7 +178,7 @@ static struct TicSpecial for (i = 0; i < BACKUPTICS; i++) { - streams[i] = (byte *)Malloc (256); + streams[i] = (byte *)M_Malloc (256); used[i] = 0; } okay = true; @@ -210,7 +210,7 @@ static struct TicSpecial DPrintf ("Expanding special size to %d\n", specialsize); for (i = 0; i < BACKUPTICS; i++) - streams[i] = (byte *)Realloc (streams[i], specialsize); + streams[i] = (byte *)M_Realloc (streams[i], specialsize); streamptr = streams[(maketic/ticdup)%BACKUPTICS] + streamoffs; } @@ -1911,7 +1911,7 @@ void FDynamicBuffer::SetData (const byte *data, int len) if (len > m_BufferLen) { m_BufferLen = (len + 255) & ~255; - m_Data = (byte *)Realloc (m_Data, m_BufferLen); + m_Data = (byte *)M_Realloc (m_Data, m_BufferLen); } if (data) { diff --git a/src/d_protocol.cpp b/src/d_protocol.cpp index e50c8fd72..433ad4d28 100644 --- a/src/d_protocol.cpp +++ b/src/d_protocol.cpp @@ -124,9 +124,16 @@ int UnpackUserCmd (usercmd_t *ucmd, const usercmd_t *basis, byte **stream) byte flags; if (basis != NULL) - memcpy (ucmd, basis, sizeof(usercmd_t)); + { + if (basis != ucmd) + { + memcpy (ucmd, basis, sizeof(usercmd_t)); + } + } else + { memset (ucmd, 0, sizeof(usercmd_t)); + } flags = ReadByte (stream); diff --git a/src/dobject.cpp b/src/dobject.cpp index b8a6a4ec5..1112d8b78 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -85,7 +85,7 @@ void TypeInfo::RegisterType () if (m_NumTypes == m_MaxTypes) { m_MaxTypes = m_MaxTypes ? m_MaxTypes*2 : 256; - m_Types = (TypeInfo **)Realloc (m_Types, m_MaxTypes * sizeof(*m_Types)); + m_Types = (TypeInfo **)M_Realloc (m_Types, m_MaxTypes * sizeof(*m_Types)); } m_Types[m_NumTypes] = this; TypeIndex = m_NumTypes; @@ -162,7 +162,7 @@ const TypeInfo *TypeInfo::IFindType (const char *name) // Create a new object that this type represents DObject *TypeInfo::CreateNew () const { - BYTE *mem = (BYTE *)Malloc (SizeOf); + BYTE *mem = (BYTE *)M_Malloc (SizeOf); ConstructNative (mem); ((DObject *)mem)->SetClass (const_cast(this)); diff --git a/src/dobject.h b/src/dobject.h index 254ec7851..a7309e654 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -310,7 +310,7 @@ public: void *operator new(size_t len) { - return Malloc(len); + return M_Malloc(len); } void operator delete (void *mem) diff --git a/src/farchive.cpp b/src/farchive.cpp index 90a954c62..b7dbc2984 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -202,7 +202,7 @@ void FCompressedFile::PostOpen () sizes[0] = SWAP_DWORD (sizes[0]); sizes[1] = SWAP_DWORD (sizes[1]); unsigned int len = sizes[0] == 0 ? sizes[1] : sizes[0]; - m_Buffer = (byte *)Malloc (len+8); + m_Buffer = (byte *)M_Malloc (len+8); fread (m_Buffer+8, len, 1, m_File); sizes[0] = SWAP_DWORD (sizes[0]); sizes[1] = SWAP_DWORD (sizes[1]); @@ -256,7 +256,7 @@ FFile &FCompressedFile::Write (const void *mem, unsigned int len) m_MaxBufferSize = m_MaxBufferSize ? m_MaxBufferSize * 2 : 16384; } while (m_Pos + len > m_MaxBufferSize); - m_Buffer = (byte *)Realloc (m_Buffer, m_MaxBufferSize); + m_Buffer = (byte *)M_Realloc (m_Buffer, m_MaxBufferSize); } if (len == 1) m_Buffer[m_Pos] = *(BYTE *)mem; @@ -357,7 +357,7 @@ void FCompressedFile::Implode () } m_MaxBufferSize = m_BufferSize = ((outlen == 0) ? len : outlen); - m_Buffer = (BYTE *)Malloc (m_BufferSize + 8); + m_Buffer = (BYTE *)M_Malloc (m_BufferSize + 8); m_Pos = 0; DWORD *lens = (DWORD *)(m_Buffer); @@ -384,7 +384,7 @@ void FCompressedFile::Explode () cprlen = BigLong(ints[0]); expandsize = BigLong(ints[1]); - expand = (unsigned char *)Malloc (expandsize); + expand = (unsigned char *)M_Malloc (expandsize); if (cprlen) { int r; @@ -467,7 +467,7 @@ bool FCompressedMemFile::Open () m_Mode = EWriting; m_BufferSize = 0; m_MaxBufferSize = 16384; - m_Buffer = (unsigned char *)Malloc (16384); + m_Buffer = (unsigned char *)M_Malloc (16384); m_Pos = 0; return true; } @@ -527,7 +527,7 @@ void FCompressedMemFile::Serialize (FArchive &arc) arc << sizes[0] << sizes[1]; DWORD len = sizes[0] == 0 ? sizes[1] : sizes[0]; - m_Buffer = (BYTE *)Malloc (len+8); + m_Buffer = (BYTE *)M_Malloc (len+8); ((DWORD *)m_Buffer)[0] = SWAP_DWORD(sizes[0]); ((DWORD *)m_Buffer)[1] = SWAP_DWORD(sizes[1]); arc.Read (m_Buffer+8, len); @@ -550,7 +550,7 @@ FPNGChunkFile::FPNGChunkFile (FILE *file, DWORD id) FPNGChunkFile::FPNGChunkFile (FILE *file, DWORD id, unsigned int chunklen) : FCompressedFile (file, EReading, true, false), m_ChunkID (id) { - m_Buffer = (byte *)Malloc (chunklen); + m_Buffer = (byte *)M_Malloc (chunklen); m_BufferSize = chunklen; fread (m_Buffer, chunklen, 1, m_File); // Skip the CRC for now. Maybe later it will be used. @@ -1371,7 +1371,7 @@ DWORD FArchive::MapObject (const DObject *obj) if (m_ObjectCount >= m_MaxObjectCount) { m_MaxObjectCount = m_MaxObjectCount ? m_MaxObjectCount * 2 : 1024; - m_ObjectMap = (ObjectMap *)Realloc (m_ObjectMap, sizeof(ObjectMap)*m_MaxObjectCount); + m_ObjectMap = (ObjectMap *)M_Realloc (m_ObjectMap, sizeof(ObjectMap)*m_MaxObjectCount); for (i = m_ObjectCount; i < m_MaxObjectCount; i++) { m_ObjectMap[i].hashNext = ~0; diff --git a/src/g_game.cpp b/src/g_game.cpp index b9bbfb57f..4311f3dbe 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2138,7 +2138,7 @@ void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf) ptrdiff_t body = demobodyspot - demobuffer; // [RH] Allocate more space for the demo maxdemosize += 0x20000; - demobuffer = (byte *)Realloc (demobuffer, maxdemosize); + demobuffer = (byte *)M_Realloc (demobuffer, maxdemosize); demo_p = demobuffer + pos; lenspot = demobuffer + spot; democompspot = demobuffer + comp; @@ -2164,7 +2164,7 @@ void G_RecordDemo (char* name) maxdemosize = atoi(v)*1024; if (maxdemosize < 0x20000) maxdemosize = 0x20000; - demobuffer = (byte *)Malloc (maxdemosize); + demobuffer = (byte *)M_Malloc (maxdemosize); demorecording = true; } diff --git a/src/g_level.cpp b/src/g_level.cpp index a75e71a14..202197a41 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -537,7 +537,7 @@ static void G_DoParseMapInfo (int lump) if (levelindex == -1) { levelindex = numwadlevelinfos++; - wadlevelinfos = (level_info_t *)Realloc (wadlevelinfos, sizeof(level_info_t)*numwadlevelinfos); + wadlevelinfos = (level_info_t *)M_Realloc (wadlevelinfos, sizeof(level_info_t)*numwadlevelinfos); } levelinfo = wadlevelinfos + levelindex; memcpy (levelinfo, &defaultinfo, sizeof(*levelinfo)); @@ -602,7 +602,7 @@ static void G_DoParseMapInfo (int lump) if (clusterindex == -1) { clusterindex = numwadclusterinfos++; - wadclusterinfos = (cluster_info_t *)Realloc (wadclusterinfos, sizeof(cluster_info_t)*numwadclusterinfos); + wadclusterinfos = (cluster_info_t *)M_Realloc (wadclusterinfos, sizeof(cluster_info_t)*numwadclusterinfos); clusterinfo = wadclusterinfos + clusterindex; } else @@ -836,7 +836,7 @@ static void ParseMapInfoLower (MapInfoHandler *handlers, if (FindWadClusterInfo (sc_Number) == -1) { int clusterindex = numwadclusterinfos++; - wadclusterinfos = (cluster_info_t *)Realloc (wadclusterinfos, sizeof(cluster_info_t)*numwadclusterinfos); + wadclusterinfos = (cluster_info_t *)M_Realloc (wadclusterinfos, sizeof(cluster_info_t)*numwadclusterinfos); clusterinfo = wadclusterinfos + clusterindex; memset (clusterinfo, 0, sizeof(cluster_info_t)); clusterinfo->cluster = sc_Number; diff --git a/src/m_alloc.h b/src/m_alloc.h index 2b3bd46e1..ae8853cd8 100644 --- a/src/m_alloc.h +++ b/src/m_alloc.h @@ -41,18 +41,19 @@ // except they bomb out with an error requester // when they can't get the memory. -void *Malloc (size_t size); -void *Calloc (size_t num, size_t size); -void *Realloc (void *memblock, size_t size); +void *M_Malloc (size_t size); +void *M_Calloc (size_t num, size_t size); +void *M_Realloc (void *memblock, size_t size); #else #include #include -inline void *Malloc(size_t size) { return malloc (size); } -inline void *Calloc(size_t num, size_t size) { return calloc (num, size); } -inline void *Realloc(void *memblock, size_t size) { return realloc (memblock, size); } +#define M_Malloc(size) malloc(size) +#define M_Calloc(num, size) calloc(num, size) +#define M_Realloc(memblock, size) realloc(memblock, size) + #endif #endif //__M_ALLOC_H__ diff --git a/src/m_misc.cpp b/src/m_misc.cpp index f0f7e5f6e..6d7a0ff2d 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -182,7 +182,7 @@ void M_FindResponseFile (void) if (argc != 0) { - argv = (char **)Malloc (argc*sizeof(char *) + argsize); + argv = (char **)M_Malloc (argc*sizeof(char *) + argsize); argv[i] = (char *)argv + argc*sizeof(char *); ParseCommandLine (file, NULL, argv+i); diff --git a/src/name.h b/src/name.h index 82c9bf566..ed6c90fb8 100644 --- a/src/name.h +++ b/src/name.h @@ -82,45 +82,22 @@ private: static bool Inited; #ifndef __GNUC__ - template<> friend bool NeedsDestructor () { return true; } - template<> friend void CopyForTArray (MainName &dst, MainName &src) { dst.NextHash = src.NextHash; CopyForTArray (dst.Text, src.Text); } - template<> friend void ConstructInTArray (MainName *dst, const MainName &src) - { - new (dst) FName::MainName(src); - } - template<> friend void ConstructEmptyInTArray (MainName *dst) - { - new (dst) FName::MainName; - } #else - template friend inline bool NeedsDestructor (); template friend inline void CopyForTArray (MainName &dst, MainName &src); - template friend inline void ConstructInTArray (MainName *dst, const MainName &src); - template friend inline void ConstructEmptyInTArray (MainName *dst); #endif }; #ifdef __GNUC__ -template<> inline bool NeedsDestructor () { return true; } - template<> inline void CopyForTArray (FName::MainName &dst, FName::MainName &src) { dst.NextHash = src.NextHash; CopyForTArray (dst.Text, src.Text); } -template<> inline void ConstructInTArray (FName::MainName *dst, const FName::MainName &src) -{ - new (dst) FName::MainName(src); -} -template<> inline void ConstructEmptyInTArray (FName::MainName *dst) -{ - new (dst) FName::MainName; -} #endif #endif diff --git a/src/p_local.h b/src/p_local.h index f6c5b04e2..fa45ed2fc 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -476,7 +476,6 @@ extern polyspawns_t *polyspawns; // [RH] list of polyobject things to spawn BOOL PO_MovePolyobj (int num, int x, int y); BOOL PO_RotatePolyobj (int num, angle_t angle); void PO_Init (); -void PO_DeInit (); BOOL PO_Busy (int polyobj); // diff --git a/src/p_map.cpp b/src/p_map.cpp index bced2ff87..c34a434a4 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4260,7 +4260,7 @@ msecnode_t *P_GetSecnode() } else { - node = (msecnode_t *)Malloc (sizeof(*node)); + node = (msecnode_t *)M_Malloc (sizeof(*node)); } return node; } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index a19a24705..b23b53777 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -2853,6 +2853,12 @@ void P_FreeLevelData () delete[] PolyBlockMap; PolyBlockMap = NULL; } + po_NumPolyobjs = 0; + if (polyobjs != NULL) + { + delete[] polyobjs; + polyobjs = NULL; + } if (rejectmatrix != NULL) { delete[] rejectmatrix; @@ -2951,7 +2957,6 @@ void P_SetupLevel (char *lumpname, int position) // [RH] clear out the mid-screen message C_MidPrint (NULL); - PolyBlockMap = NULL; // Free all level data from the previous map P_FreeLevelData (); @@ -3181,8 +3186,6 @@ void P_SetupLevel (char *lumpname, int position) for (i = 0; i < BODYQUESIZE; i++) bodyque[i] = NULL; - PO_DeInit (); // Flush polyobjs from previous map - deathmatchstarts.Clear (); if (!buildmap) diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 036b34000..1ca5d3694 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -461,7 +461,7 @@ static void ParseAnim (bool istex) sink.Countdown = frames[0].SpeedMin; sink.NumFrames = frames.Size(); - newAnim = (FAnimDef *)Malloc (sizeof(FAnimDef) + (frames.Size()-1)*sizeof(FAnimDef::FAnimFrame)); + newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1)*sizeof(FAnimDef::FAnimFrame)); *newAnim = sink; for (i = 0; i < frames.Size(); ++i) @@ -471,7 +471,7 @@ static void ParseAnim (bool istex) } else { - newAnim = (FAnimDef *)Malloc (sizeof(FAnimDef)); + newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef)); *newAnim = sink; } @@ -588,7 +588,7 @@ void P_InitPicAnims (void) anim.Frames[0].FramePic = anim.BasePic; anim.Countdown = anim.Frames[0].SpeedMin - 1; - newAnim = (FAnimDef *)Malloc (sizeof(FAnimDef)); + newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef)); *newAnim = anim; Anims.Push (newAnim); } @@ -600,7 +600,7 @@ void P_InitPicAnims (void) void P_AddSimpleAnim (int picnum, int animcount, int animtype, int animspeed) { - FAnimDef *anim = (FAnimDef *)Malloc (sizeof(FAnimDef)); + FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef)); anim->bUniqueFrames = false; anim->CurFrame = 0; anim->BasePic = picnum; diff --git a/src/p_switch.cpp b/src/p_switch.cpp index c44c2a707..65175d3f4 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -149,8 +149,8 @@ void P_InitSwitchList () ((gameinfo.maxSwitch & ~15) == (list_p[18] & ~15)) && TexMan.CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags) >= 0) { - def1 = (FSwitchDef *)Malloc (sizeof(FSwitchDef)); - def2 = (FSwitchDef *)Malloc (sizeof(FSwitchDef)); + def1 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef)); + def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef)); def1->PreTexture = def2->u.Textures[2] = TexMan.CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags); def2->PreTexture = def1->u.Textures[2] = TexMan.CheckForTexture (list_p + 9, FTexture::TEX_Wall, texflags); def1->Sound = def2->Sound = 0; @@ -300,7 +300,7 @@ void P_ProcessSwitchDef () // it to the original texture without doing anything interesting if (def2 == NULL) { - def2 = (FSwitchDef *)Malloc (sizeof(FSwitchDef)); + def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef)); def2->Sound = def1->Sound; def2->NumFrames = 1; def2->u.Times[0] = 0; @@ -399,7 +399,7 @@ FSwitchDef *ParseSwitchDef (bool ignoreBad) { return NULL; } - def = (FSwitchDef *)Malloc (myoffsetof (FSwitchDef, u.Times[0]) + numframes * 6); + def = (FSwitchDef *)M_Malloc (myoffsetof (FSwitchDef, u.Times[0]) + numframes * 6); def->Sound = sound; def->NumFrames = numframes; memcpy (&def->u.Times[0], times, numframes * 4); diff --git a/src/p_terrain.cpp b/src/p_terrain.cpp index bbb556747..3c9f903e8 100644 --- a/src/p_terrain.cpp +++ b/src/p_terrain.cpp @@ -268,7 +268,7 @@ void P_InitTerrainTypes () int size; size = (TexMan.NumTextures()+1)*sizeof(byte); - TerrainTypes = (byte *)Malloc (size); + TerrainTypes = (byte *)M_Malloc (size); memset (TerrainTypes, 0, size); MakeDefaultTerrain (); diff --git a/src/po_man.cpp b/src/po_man.cpp index fabbea880..d6cadc4ff 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -1541,27 +1541,6 @@ void PO_Init (void) KillSegLists (); } -//========================================================================== -// -// PO_DeInit -// -//========================================================================== - -void PO_DeInit () -{ - po_NumPolyobjs = 0; - if (polyobjs != NULL) - { - delete[] polyobjs; - polyobjs = NULL; - } - if (PolyBlockMap != NULL) - { - delete[] PolyBlockMap; - PolyBlockMap = NULL; - } -} - //========================================================================== // // PO_Busy diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index ab989bb03..b6e322d7a 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -119,7 +119,7 @@ void R_ClearDrawSegs (void) if (drawsegs == NULL) { MaxDrawSegs = 256; // [RH] Default. Increased as needed. - firstdrawseg = drawsegs = (drawseg_t *)Malloc (MaxDrawSegs * sizeof(drawseg_t)); + firstdrawseg = drawsegs = (drawseg_t *)M_Malloc (MaxDrawSegs * sizeof(drawseg_t)); } FirstInterestingDrawseg = 0; InterestingDrawsegs.Clear (); diff --git a/src/r_data.cpp b/src/r_data.cpp index c57b8c7aa..c90ad4fe5 100644 --- a/src/r_data.cpp +++ b/src/r_data.cpp @@ -308,7 +308,7 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype) int height; int width; - foo = (patch_t *)Malloc (data.GetLength()); + foo = (patch_t *)M_Malloc (data.GetLength()); data.Seek (-4, SEEK_CUR); data.Read (foo, data.GetLength()); @@ -823,7 +823,7 @@ FTexture::Span **FTexture::CreateSpans (const BYTE *pixels) const if (!bMasked) { // Texture does not have holes, so it can use a simpler span structure - spans = (Span **)Malloc (sizeof(Span*)*Width + sizeof(Span)*2); + spans = (Span **)M_Malloc (sizeof(Span*)*Width + sizeof(Span)*2); span = (Span *)&spans[Width]; for (int x = 0; x < Width; ++x) { @@ -867,7 +867,7 @@ FTexture::Span **FTexture::CreateSpans (const BYTE *pixels) const } // Allocate space for the spans - spans = (Span **)Malloc (sizeof(Span*)*numcols + sizeof(Span)*numspans); + spans = (Span **)M_Malloc (sizeof(Span*)*numcols + sizeof(Span)*numspans); // Fill in the spans for (x = 0, span = (Span *)&spans[numcols], data_p = pixels; x < numcols; ++x) @@ -1271,7 +1271,7 @@ void FPatchTexture::MakeTexture () } // Create the spans - Spans = (Span **)Malloc (sizeof(Span*)*Width + sizeof(Span)*numspans); + Spans = (Span **)M_Malloc (sizeof(Span*)*Width + sizeof(Span)*numspans); spanstuffer = (Span *)((BYTE *)Spans + sizeof(Span*)*Width); warned = false; @@ -1393,7 +1393,7 @@ void FPatchTexture::HackHack (int newheight) } // Create the spans - Spans = (Span **)Malloc (sizeof(Span *)*Width + sizeof(Span)*Width*2); + Spans = (Span **)M_Malloc (sizeof(Span *)*Width + sizeof(Span)*Width*2); Span *span = (Span *)&Spans[Width]; diff --git a/src/r_plane.cpp b/src/r_plane.cpp index c62ed1d62..30da3bc6f 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -474,7 +474,7 @@ static visplane_t *new_visplane (unsigned hash) if (check == NULL) { - check = (visplane_t *)Calloc (1, sizeof(*check) + sizeof(*check->top)*(MAXWIDTH*2)); + check = (visplane_t *)M_Calloc (1, sizeof(*check) + sizeof(*check->top)*(MAXWIDTH*2)); check->bottom = &check->top[MAXWIDTH+2]; } else if (NULL == (freetail = freetail->next)) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 319b675d9..03807547a 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -1104,7 +1104,7 @@ void R_CheckDrawSegs () { // [RH] Grab some more drawsegs size_t newdrawsegs = MaxDrawSegs ? MaxDrawSegs*2 : 32; ptrdiff_t firstofs = firstdrawseg - drawsegs; - drawsegs = (drawseg_t *)Realloc (drawsegs, newdrawsegs * sizeof(drawseg_t)); + drawsegs = (drawseg_t *)M_Realloc (drawsegs, newdrawsegs * sizeof(drawseg_t)); firstdrawseg = drawsegs + firstofs; ds_p = drawsegs + MaxDrawSegs; MaxDrawSegs = newdrawsegs; @@ -1125,7 +1125,7 @@ void R_CheckOpenings (size_t need) do maxopenings = maxopenings ? maxopenings*2 : 16384; while (need > maxopenings); - openings = (short *)Realloc (openings, maxopenings * sizeof(*openings)); + openings = (short *)M_Realloc (openings, maxopenings * sizeof(*openings)); DPrintf ("MaxOpenings increased to %u\n", maxopenings); } } diff --git a/src/r_things.cpp b/src/r_things.cpp index f3f72d64f..a8be81df3 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -808,7 +808,7 @@ vissprite_t *R_NewVisSprite (void) ptrdiff_t prevvisspritenum = vissprite_p - vissprites; MaxVisSprites = MaxVisSprites ? MaxVisSprites * 2 : 128; - vissprites = (vissprite_t **)Realloc (vissprites, MaxVisSprites * sizeof(vissprite_t)); + vissprites = (vissprite_t **)M_Realloc (vissprites, MaxVisSprites * sizeof(vissprite_t)); lastvissprite = &vissprites[MaxVisSprites]; firstvissprite = &vissprites[firstvisspritenum]; vissprite_p = &vissprites[prevvisspritenum]; diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 4591b6efc..70ba53ad1 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -946,7 +946,7 @@ static void S_AddSNDINFO (int lump) SC_MustGetString(); FString musname (sc_String); SC_MustGetFloat(); - FMusicVolume *mv = (FMusicVolume *)Malloc (sizeof(*mv) + musname.Len()); + FMusicVolume *mv = (FMusicVolume *)M_Malloc (sizeof(*mv) + musname.Len()); mv->Volume = sc_Float; strcpy (mv->MusicName, musname); mv->Next = MusicVolumes; diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index 5492bd93d..c6e84e92e 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -648,7 +648,7 @@ void S_ParseSndSeq (int levellump) static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, const TArray &ScriptTemp) { - Sequences[curseq] = (FSoundSequence *)Malloc (sizeof(FSoundSequence) + sizeof(DWORD)*ScriptTemp.Size()); + Sequences[curseq] = (FSoundSequence *)M_Malloc (sizeof(FSoundSequence) + sizeof(DWORD)*ScriptTemp.Size()); Sequences[curseq]->SeqName = seqname; Sequences[curseq]->Slot = slot; Sequences[curseq]->StopSound = stopsound; diff --git a/src/stringtable.cpp b/src/stringtable.cpp index db4323e61..3cd48be06 100644 --- a/src/stringtable.cpp +++ b/src/stringtable.cpp @@ -258,7 +258,7 @@ void FStringTable::LoadLanguage (int lumpnum, DWORD code, bool exactMatch, int p } if (entry == NULL || cmpval > 0) { - entry = (StringEntry *)Malloc (sizeof(*entry) + strText.Len() + strName.Len()); + entry = (StringEntry *)M_Malloc (sizeof(*entry) + strText.Len() + strName.Len()); entry->Next = *pentry; *pentry = entry; strcpy (entry->String, strText.GetChars()); @@ -380,7 +380,7 @@ void FStringTable::SetString (const char *name, const char *newString) size_t namelen = strlen (name); // Create a new string entry - StringEntry *entry = (StringEntry *)Malloc (sizeof(*entry) + newlen + namelen); + StringEntry *entry = (StringEntry *)M_Malloc (sizeof(*entry) + newlen + namelen); strcpy (entry->String, newString); strcpy (entry->Name = entry->String + newlen + 1, name); entry->PassNum = 0; diff --git a/src/tarray.h b/src/tarray.h index d52314d14..466f80dcb 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -36,14 +36,11 @@ #define __TARRAY_H__ #include +#include +#include + #include "m_alloc.h" -// Specialize this function for any type that needs to have its destructor called. -template -bool NeedsDestructor () -{ - return false; -} // This function is called once for each entry in the TArray after it grows. // The old entries will be immediately freed afterwards, so if they need to @@ -51,11 +48,8 @@ bool NeedsDestructor () template void CopyForTArray (T &dst, T &src) { - dst = src; - if (NeedsDestructor()) - { - src.~T(); - } + ::new((void*)&dst) T(src); + src.~T(); } // This function is called by Push to copy the the element to an unconstructed @@ -64,8 +58,7 @@ void CopyForTArray (T &dst, T &src) template void ConstructInTArray (T *dst, const T &src) { - //new (dst) T(src); - *dst = src; + ::new((void*)dst) T(src); } // This function is much like the above function, except it is called when @@ -73,6 +66,7 @@ void ConstructInTArray (T *dst, const T &src) template void ConstructEmptyInTArray (T *dst) { + ::new((void*)dst) T; } template @@ -89,7 +83,7 @@ public: { Most = max; Count = 0; - Array = (T *)Malloc (sizeof(T)*max); + Array = (T *)M_Malloc (sizeof(T)*max); } TArray (const TArray &other) { @@ -101,7 +95,10 @@ public: { if (Array != NULL) { - DoDelete (0, Count-1); + if (Count > 0) + { + DoDelete (0, Count-1); + } free (Array); } DoCopy (other); @@ -112,8 +109,14 @@ public: { if (Array) { - DoDelete (0, Count-1); + if (Count > 0) + { + DoDelete (0, Count-1); + } free (Array); + Array = NULL; + Count = 0; + Most = 0; } } T &operator[] (unsigned int index) const @@ -142,11 +145,43 @@ public: } void Delete (unsigned int index) { - DoDelete (index, index); - if (index < Count-1) - memmove (Array + index, Array + index + 1, (Count - index - 1) * sizeof(T)); if (index < Count) + { + for (unsigned int i = index; i < Count - 1; ++i) + { + Array[i] = Array[i+1]; + } Count--; + DoDelete (Count, Count); + } + } + // Inserts an item into the array, shifting elements as needed + void Insert (unsigned int index, const T &item) + { + if (index >= Count) + { + // Inserting somewhere past the end of the array, so we can + // just add it without moving things. + Resize (index + 1); + ConstructInTArray (&Array[index], item); + } + else + { + // Inserting somewhere in the middle of the array, so make + // room for it and shift old entries out of the way. + + Resize (Count + 1); + + // Now copy items from the index and onward + for (unsigned int i = Count - 1; i-- > index; ) + { + Array[i+1] = Array[i]; + } + + // Now put the new element in + DoDelete (index, index); + ConstructInTArray (&Array[index], item); + } } void ShrinkToFit () { @@ -186,12 +221,9 @@ public: { Grow (amount - Count); } - if (NeedsDestructor()) + for (unsigned int i = Count; i < amount; ++i) { - for (unsigned int i = Count; i < amount; ++i) - { - ConstructEmptyInTArray (&Array[i]); - } + ConstructEmptyInTArray (&Array[i]); } Count = amount; } @@ -217,8 +249,11 @@ public: } void Clear () { - DoDelete (0, Count-1); - Count = 0; + if (Count > 0) + { + DoDelete (0, Count-1); + Count = 0; + } } private: T *Array; @@ -230,7 +265,7 @@ private: Most = Count = other.Count; if (Count != 0) { - Array = (T *)Malloc (sizeof(T)*Most); + Array = (T *)M_Malloc (sizeof(T)*Most); for (unsigned int i = 0; i < Count; ++i) { Array[i] = other.Array[i]; @@ -244,7 +279,7 @@ private: void DoResize () { - T *newarray = (T *)Malloc (sizeof(T)*Most); + T *newarray = (T *)M_Malloc (sizeof(T)*Most); for (unsigned int i = 0; i < Count; ++i) { CopyForTArray (newarray[i], Array[i]); @@ -255,12 +290,10 @@ private: void DoDelete (unsigned int first, unsigned int last) { - if (NeedsDestructor()) + assert (last != ~0u); + for (unsigned int i = first; i <= last; ++i) { - for (unsigned int i = first; i <= last; ++i) - { - Array[i].~T(); - } + Array[i].~T(); } } }; diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 4614d9e9e..d61db895e 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -256,7 +256,7 @@ static DWORD Zip_FindCentralDir(FileReader * fin) FileSize = fin->Tell(); uMaxBack = MIN(0xffff, FileSize); - buf = (unsigned char*)Malloc(BUFREADCOMMENT+4); + buf = (unsigned char*)M_Malloc(BUFREADCOMMENT+4); if (buf == NULL) return 0; uBackRead = 4; @@ -379,7 +379,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt BloodCrypt (lumps, header.rff.DirOfs, header.rff.NumLumps * sizeof(rfflump_t)); NumLumps += header.rff.NumLumps; - LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); + LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); lump_p = &LumpInfo[startlump]; for (i = 0, rff_p = lumps; i < header.rff.NumLumps; ++i, ++rff_p) @@ -433,7 +433,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt pos = sizeof(grpinfo_t) + header.grp.NumLumps * sizeof(grplump_t); NumLumps += header.grp.NumLumps; - LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); + LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); lump_p = &LumpInfo[startlump]; for (i = 0, grp_p = lumps; i < header.grp.NumLumps; ++i, ++grp_p) @@ -479,7 +479,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt } NumLumps += LittleShort(info.wEntryCount); - LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); + LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); lump_p = &LumpInfo[startlump]; // Load the entire central directory. Too bad that this contains variable length entries... @@ -599,7 +599,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt } // Resize the lump record array to its actual size NumLumps -= skipped; - LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); + LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); // Entries in Zips are sorted alphabetically. qsort(LumpInfo + startlump, NumLumps - startlump, sizeof(LumpRecord), lumpcmp); @@ -623,7 +623,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt header.magic[0] != ZIP_ID && (header.magic[0] != GRP_ID_0 || header.magic[1] != GRP_ID_1 || header.magic[2] != GRP_ID_2)) { - LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); + LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); lump_p = &LumpInfo[startlump]; for (i = startlump; i < (unsigned)NumLumps; i++, lump_p++, fileinfo++) { @@ -649,7 +649,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt wadinfo->FirstLump = startlump; wadinfo->LastLump = NumLumps - 1; - Wads = (WadFileRecord **)Realloc (Wads, (++NumWads)*sizeof(WadFileRecord*)); + Wads = (WadFileRecord **)M_Realloc (Wads, (++NumWads)*sizeof(WadFileRecord*)); Wads[NumWads-1] = wadinfo; // [RH] Put the Strife Teaser voices into the voices namespace @@ -1153,7 +1153,7 @@ void FWadCollection::ScanForFlatHack (int startlump) } } ++NumLumps; - LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); + LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); for (; i > j; --i) { LumpInfo[i+1] = LumpInfo[i]; @@ -1374,7 +1374,7 @@ int FWadCollection::MergeLumps (const char *start, const char *end, int space) if (newlumps) { if (size_t(oldlumps + newlumps) >= NumLumps) - LumpInfo = (LumpRecord *)Realloc (LumpInfo, (oldlumps + newlumps + 1) * sizeof(LumpRecord) ); + LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, (oldlumps + newlumps + 1) * sizeof(LumpRecord) ); memcpy (LumpInfo + oldlumps, newlumpinfos, sizeof(LumpRecord) * newlumps); markerpos = oldlumps; diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 754879e85..e9e1acbea 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -646,11 +646,12 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n SetUnhandledExceptionFilter (CatchAllExceptions); } -#ifdef _DEBUG +#if defined(_DEBUG) && defined(_MSC_VER) // Uncomment this line to make the Visual C++ CRT check the heap before // every allocation and deallocation. This will be slow, but it can be a // great help in finding problem areas. //_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF); + _CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF); #endif DoMain (hInstance); diff --git a/src/zstring.h b/src/zstring.h index b9fd13da1..95273ff4e 100644 --- a/src/zstring.h +++ b/src/zstring.h @@ -161,8 +161,6 @@ protected: char *Chars; #ifndef __GNUC__ - template<> friend bool NeedsDestructor () { return true; } - template<> friend void CopyForTArray (FString &dst, FString &src) { // When a TArray is resized, we just need to update the Owner, because @@ -176,18 +174,8 @@ protected: ((FString::StringHeader *)(chars - sizeof(FString::StringHeader)))->Owner = &dst; } } - template<> friend void ConstructInTArray (FString *dst, const FString &src) - { - new (dst) FString(src); - } - template<> friend void ConstructEmptyInTArray (FString *dst) - { - new (dst) FString; - } #else template friend inline void CopyForTArray (FString &dst, FString &src); - template friend inline void ConstructInTArray (FString *dst, const FString &src); - template friend inline void ConstructEmptyInTArray (FString *dst); #endif private: @@ -201,7 +189,6 @@ private: }; #ifdef __GNUC__ -template<> inline bool NeedsDestructor () { return true; } template<> inline void CopyForTArray (FString &dst, FString &src) { // When a TArray is resized, we just need to update the Owner, because @@ -215,14 +202,6 @@ template<> inline void CopyForTArray (FString &dst, FString &src) ((FString::StringHeader *)(chars - sizeof(FString::StringHeader)))->Owner = &dst; } } -template<> inline void ConstructInTArray (FString *dst, const FString &src) -{ - new (dst) FString(src); -} -template<> inline void ConstructEmptyInTArray (FString *dst) -{ - new (dst) FString; -} #endif namespace StringFormat diff --git a/src/zstringpool.cpp b/src/zstringpool.cpp index 855319ac0..82b9488b7 100644 --- a/src/zstringpool.cpp +++ b/src/zstringpool.cpp @@ -31,7 +31,7 @@ struct FString::Pool char *Realloc (char *chars, size_t newlen); void Free (char *chars); void MergeFreeBlocks (StringHeader *block); - void CollectGarbage (bool noGenerations); + void CollectGarbage (); bool BigEnough (size_t len) const; size_t RoundLen (size_t len) const; @@ -40,8 +40,6 @@ struct FString::Pool char *PoolData; char *MaxAlloc; StringHeader *NextAlloc; - StringHeader *GarbageStart; - int GenerationNum; }; // The PoolGroup does not get a constructor, because there is no way to @@ -100,13 +98,8 @@ char *FString::PoolGroup::Alloc (FString *owner, size_t len) } if (best->BigEnough (len)) { - best->CollectGarbage (false); + best->CollectGarbage (); mem = best->Alloc (owner, len); - if (mem == NULL) - { - best->CollectGarbage (true); - mem = best->Alloc (owner, len); - } // Move the pool to the front of the list *bestprev = best->Next; best->Next = Pools; @@ -151,7 +144,10 @@ char *FString::PoolGroup::Realloc (FString *owner, char *chars, size_t newlen) void FString::PoolGroup::Free (char *chars) { Pool *pool = FindPool (chars); - pool->Free (chars); + if (pool != NULL) + { + pool->Free (chars); + } } FString::Pool *FString::PoolGroup::FindPool (char *chars) const @@ -187,8 +183,6 @@ FString::Pool::Pool (size_t minSize) NextAlloc = (StringHeader *)PoolData; NextAlloc->Owner = NULL; NextAlloc->Len = minSize; - GarbageStart = NextAlloc; - GenerationNum = 0; } FString::Pool::~Pool () @@ -199,19 +193,19 @@ FString::Pool::~Pool () // all the strings stored in it. So we need to walk through the pool // and make any owned strings un-owned. StringHeader *str; + StringHeader *laststr; for (str = (StringHeader *)PoolData; str < NextAlloc; ) { if (str->Owner != NULL) { - str->Owner->Chars = NULL; - str->Owner = NULL; - str = (StringHeader *)((char *)str + RoundLen(str->Len)); - } - else - { - str = (StringHeader *)((char *)str + str->Len); + FString *owner = str->Owner; + assert (owner->Chars == (char *)str + sizeof(StringHeader)); + Free ((char *)str + sizeof(StringHeader)); + owner->Chars = ""; } + laststr = str; + str = (StringHeader *)((char *)str + str->Len); } delete[] PoolData; @@ -308,6 +302,21 @@ char *FString::Pool::Realloc (char *chars, size_t newlen) void FString::Pool::Free (char *chars) { +#ifdef _DEBUG + for (StringHeader *str = (StringHeader *)PoolData; str < NextAlloc; ) + { + if (str->Owner != NULL) + { + assert (str->Owner->Chars == (char *)str + sizeof(StringHeader)); + str = (StringHeader *)((char *)str + RoundLen(str->Len)); + } + else + { + str = (StringHeader *)((char *)str + str->Len); + } + } +#endif + StringHeader *head = (StringHeader *)(chars - sizeof(StringHeader)); size_t truelen = RoundLen (head->Len); @@ -316,6 +325,25 @@ void FString::Pool::Free (char *chars) head->Owner = NULL; head->Len = truelen; MergeFreeBlocks (head); + +#ifdef _DEBUG + memset (head + 1, 0xCE, head->Len - sizeof(StringHeader)); +#endif + +#ifdef _DEBUG + for (StringHeader *str = (StringHeader *)PoolData; str < NextAlloc; ) + { + if (str->Owner != NULL) + { + assert (str->Owner->Chars == (char *)str + sizeof(StringHeader)); + str = (StringHeader *)((char *)str + RoundLen(str->Len)); + } + else + { + str = (StringHeader *)((char *)str + str->Len); + } + } +#endif } void FString::Pool::MergeFreeBlocks (StringHeader *head) @@ -331,10 +359,6 @@ void FString::Pool::MergeFreeBlocks (StringHeader *head) // If this chain of blocks meets up with the free space, then they can join up with it. if (block == NextAlloc) { - if (GarbageStart == NextAlloc) - { - GarbageStart = head; - } NextAlloc = head; head->Len = MaxAlloc - (char *)head; } @@ -354,19 +378,13 @@ size_t FString::Pool::RoundLen (size_t len) const return (len + 1 + sizeof(StringHeader) + BLOCK_GRANULARITY - 1) & ~(BLOCK_GRANULARITY - 1); } -void FString::Pool::CollectGarbage (bool noGenerations) +void FString::Pool::CollectGarbage () { // This is a generational garbage collector. The space occupied by strings from // the first two generations will not be collected unless noGenerations is set true. - if (noGenerations) - { - GarbageStart = (StringHeader *)PoolData; - GenerationNum = 0; - } - StringHeader *moveto, *movefrom; - moveto = movefrom = GarbageStart; + moveto = movefrom = (StringHeader *)PoolData; while (movefrom < NextAlloc) { @@ -397,11 +415,6 @@ void FString::Pool::CollectGarbage (bool noGenerations) } else if (FreeSpace != 0) FreeSpace = FreeSpace; - - if (++GenerationNum <= 3) - { - GarbageStart = moveto; - } } #else char *FString::PoolGroup::Alloc (FString *owner, size_t len)