- 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


SVN r75 (trunk)
This commit is contained in:
Randy Heit 2006-05-04 03:49:46 +00:00
parent ea3b76815d
commit c8cdb52863
38 changed files with 264 additions and 242 deletions

View file

@ -1,4 +1,20 @@
May 3, 2006 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 - Removed -bpal parameter. Blood's blood.pal is loaded from blood.rff, and
its tiles are loaded from the same directory. its tiles are loaded from the same directory.
- RFF files now load their entire directories into the lumplist. - RFF files now load their entire directories into the lumplist.

View file

@ -244,9 +244,8 @@ const char *KeyNames[NUM_KEYS] =
"mwheelup", "mwheeldown", // the mouse wheel "mwheelup", "mwheeldown", // the mouse wheel
}; };
static char *Bindings[NUM_KEYS]; static FString Bindings[NUM_KEYS];
static FString DoubleBindings[NUM_KEYS];
static char *DoubleBindings[NUM_KEYS];
static unsigned int DClickTime[NUM_KEYS]; static unsigned int DClickTime[NUM_KEYS];
static byte DClicked[(NUM_KEYS+7)/8]; static byte DClicked[(NUM_KEYS+7)/8];
@ -343,7 +342,7 @@ CCMD (bind)
} }
else else
{ {
ReplaceString (&Bindings[i], argv[2]); Bindings[i] = argv[2];
} }
} }
else else
@ -438,7 +437,7 @@ CCMD (doublebind)
} }
else else
{ {
ReplaceString (&DoubleBindings[i], argv[2]); DoubleBindings[i] = argv[2];
} }
} }
else else
@ -455,7 +454,7 @@ CCMD (doublebind)
CCMD (rebind) CCMD (rebind)
{ {
char **bindings; FString *bindings;
if (key == 0) if (key == 0)
{ {
@ -475,7 +474,7 @@ CCMD (rebind)
if (argv.argc() > 1) 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) void C_ArchiveBindings (FConfigFile *f, bool dodouble, const char *matchcmd)
{ {
char **bindings; FString *bindings;
const char *name; const char *name;
int i; int i;
@ -660,7 +659,7 @@ void C_DoBind (const char *key, const char *bind, bool dodouble)
} }
if (keynum != 0) 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) char *C_GetBinding (int key)
{ {
return (unsigned int)key < NUM_KEYS ? Bindings[key] : NULL; return (unsigned int)key < NUM_KEYS ? Bindings[key].GetChars() : NULL;
} }

View file

@ -574,7 +574,7 @@ void AddToConsole (int printlevel, const char *text)
} }
if (size > worklen) if (size > worklen)
{ {
work = (char *)Realloc (work, size); work = (char *)M_Realloc (work, size);
worklen = size; worklen = size;
} }
if (work == NULL) 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, // or there is nothing in the history list,
// so add it to 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]); strcpy (temp->String, (char *)&buffer[2]);
temp->Older = HistHead; temp->Older = HistHead;
@ -1700,12 +1700,28 @@ void C_MidPrintBold (const char *msg)
/****** Tab completion code ******/ /****** Tab completion code ******/
static struct TabData struct TabData
{ {
int UseCount; int UseCount;
char *Name; FString Name;
} *TabCommands = NULL;
static int NumTabCommands = 0; TabData()
: UseCount(0)
{
}
TabData(const char *name)
: UseCount(1), Name(name)
{
}
TabData(const TabData &other)
: UseCount(other.UseCount), Name(other.Name)
{
}
};
static TArray<TabData> TabCommands;
static int TabPos; // Last TabCommand tabbed to static int TabPos; // Last TabCommand tabbed to
static int TabStart; // First char in CmdLine to use for tab completion static int TabStart; // First char in CmdLine to use for tab completion
static int TabSize; // Size of tab string 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; int i, cval = 1;
for (i = 0; i < NumTabCommands; i++) for (i = 0; i < TabCommands.Size(); i++)
{ {
cval = strnicmp (TabCommands[i].Name, name, len); cval = strnicmp (TabCommands[i].Name, name, len);
if (cval >= 0) if (cval >= 0)
@ -1736,15 +1752,8 @@ void C_AddTabCommand (const char *name)
} }
else else
{ {
NumTabCommands++; TabData tab(name);
TabCommands = (TabData *)Realloc (TabCommands, sizeof(struct TabData) * NumTabCommands); TabCommands.Insert (pos, tab);
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;
} }
} }
@ -1756,13 +1765,7 @@ void C_RemoveTabCommand (const char *name)
{ {
if (--TabCommands[pos].UseCount == 0) if (--TabCommands[pos].UseCount == 0)
{ {
NumTabCommands--; TabCommands.Delete(pos);
delete[] TabCommands[pos].Name;
if (pos < NumTabCommands - 1)
{
memmove (TabCommands + pos, TabCommands + pos + 1,
(NumTabCommands - pos - 1) * sizeof(struct TabData));
}
} }
} }
} }
@ -1827,7 +1830,7 @@ static void C_TabComplete (bool goForward)
} }
else else
{ // Find the last matching tab, then go one past it. { // 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) 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)) (!goForward && --TabPos < 0))
{ {
TabbedLast = false; TabbedLast = false;
@ -1878,7 +1881,7 @@ static bool C_TabCompleteList ()
nummatches = 0; nummatches = 0;
maxwidth = 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) if (FindDiffPoint (TabCommands[i].Name, (char *)(CmdLine + TabStart)) < TabSize)
{ {

View file

@ -783,6 +783,17 @@ FStringCVar::FStringCVar (const char *name, const char *def, DWORD flags, void (
DefaultValue = copystring (def); DefaultValue = copystring (def);
if (Flags & CVAR_ISDEFAULT) if (Flags & CVAR_ISDEFAULT)
Value = copystring (def); Value = copystring (def);
else
Value = NULL;
}
FStringCVar::~FStringCVar ()
{
if (Value != NULL)
{
delete[] Value;
}
delete[] DefaultValue;
} }
ECVarType FStringCVar::GetRealType () const ECVarType FStringCVar::GetRealType () const

View file

@ -257,6 +257,7 @@ class FStringCVar : public FBaseCVar
{ {
public: public:
FStringCVar (const char *name, const char *def, DWORD flags, void (*callback)(FStringCVar &)=NULL); FStringCVar (const char *name, const char *def, DWORD flags, void (*callback)(FStringCVar &)=NULL);
~FStringCVar ();
virtual ECVarType GetRealType () const; virtual ECVarType GetRealType () const;

View file

@ -306,7 +306,7 @@ static const char *IsNum (const char *str)
static FStringProd *NewStringProd (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; prod->Type = PROD_String;
strcpy (prod->Value, str); strcpy (prod->Value, str);
return prod; return prod;
@ -320,7 +320,7 @@ static FStringProd *NewStringProd (const char *str)
static FStringProd *NewStringProd (size_t len) 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->Type = PROD_String;
prod->Value[0] = 0; prod->Value[0] = 0;
return prod; return prod;
@ -334,7 +334,7 @@ static FStringProd *NewStringProd (size_t len)
static FDoubleProd *NewDoubleProd (double val) static FDoubleProd *NewDoubleProd (double val)
{ {
FDoubleProd *prod = (FDoubleProd *)Malloc (sizeof(FDoubleProd)); FDoubleProd *prod = (FDoubleProd *)M_Malloc (sizeof(FDoubleProd));
prod->Type = PROD_Double; prod->Type = PROD_Double;
prod->Value = val; prod->Value = val;
return prod; return prod;

View file

@ -1942,7 +1942,7 @@ static int PatchStrings (int dummy)
DPrintf ("[Strings]\n"); DPrintf ("[Strings]\n");
if (!holdstring) if (!holdstring)
holdstring = (char *)Malloc (maxstrlen); holdstring = (char *)M_Malloc (maxstrlen);
while ((result = GetLine()) == 1) while ((result = GetLine()) == 1)
{ {
@ -1952,7 +1952,7 @@ static int PatchStrings (int dummy)
while (maxstrlen < strlen (holdstring) + strlen (Line2) + 8) while (maxstrlen < strlen (holdstring) + strlen (Line2) + 8)
{ {
maxstrlen += 128; maxstrlen += 128;
holdstring = (char *)Realloc (holdstring, maxstrlen); holdstring = (char *)M_Realloc (holdstring, maxstrlen);
} }
strcat (holdstring, skipwhite (Line2)); strcat (holdstring, skipwhite (Line2));
stripwhite (holdstring); stripwhite (holdstring);

View file

@ -662,7 +662,7 @@ CCMD (atexit)
} }
for (int i = 1; i < argv.argc(); ++i) for (int i = 1; i < argv.argc(); ++i)
{ {
GameAtExit *record = (GameAtExit *)Malloc ( GameAtExit *record = (GameAtExit *)M_Malloc (
sizeof(GameAtExit)+strlen(argv[i])); sizeof(GameAtExit)+strlen(argv[i]));
strcpy (record->Command, argv[i]); strcpy (record->Command, argv[i]);
record->Next = ExitCmdList; record->Next = ExitCmdList;
@ -1105,7 +1105,7 @@ void D_AddFile (const char *file)
} }
file = f; 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; *wadtail = wad;
wad->next = NULL; wad->next = NULL;

View file

@ -178,7 +178,7 @@ static struct TicSpecial
for (i = 0; i < BACKUPTICS; i++) for (i = 0; i < BACKUPTICS; i++)
{ {
streams[i] = (byte *)Malloc (256); streams[i] = (byte *)M_Malloc (256);
used[i] = 0; used[i] = 0;
} }
okay = true; okay = true;
@ -210,7 +210,7 @@ static struct TicSpecial
DPrintf ("Expanding special size to %d\n", specialsize); DPrintf ("Expanding special size to %d\n", specialsize);
for (i = 0; i < BACKUPTICS; i++) 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; streamptr = streams[(maketic/ticdup)%BACKUPTICS] + streamoffs;
} }
@ -1911,7 +1911,7 @@ void FDynamicBuffer::SetData (const byte *data, int len)
if (len > m_BufferLen) if (len > m_BufferLen)
{ {
m_BufferLen = (len + 255) & ~255; m_BufferLen = (len + 255) & ~255;
m_Data = (byte *)Realloc (m_Data, m_BufferLen); m_Data = (byte *)M_Realloc (m_Data, m_BufferLen);
} }
if (data) if (data)
{ {

View file

@ -124,9 +124,16 @@ int UnpackUserCmd (usercmd_t *ucmd, const usercmd_t *basis, byte **stream)
byte flags; byte flags;
if (basis != NULL) if (basis != NULL)
memcpy (ucmd, basis, sizeof(usercmd_t)); {
if (basis != ucmd)
{
memcpy (ucmd, basis, sizeof(usercmd_t));
}
}
else else
{
memset (ucmd, 0, sizeof(usercmd_t)); memset (ucmd, 0, sizeof(usercmd_t));
}
flags = ReadByte (stream); flags = ReadByte (stream);

View file

@ -85,7 +85,7 @@ void TypeInfo::RegisterType ()
if (m_NumTypes == m_MaxTypes) if (m_NumTypes == m_MaxTypes)
{ {
m_MaxTypes = m_MaxTypes ? m_MaxTypes*2 : 256; 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; m_Types[m_NumTypes] = this;
TypeIndex = m_NumTypes; TypeIndex = m_NumTypes;
@ -162,7 +162,7 @@ const TypeInfo *TypeInfo::IFindType (const char *name)
// Create a new object that this type represents // Create a new object that this type represents
DObject *TypeInfo::CreateNew () const DObject *TypeInfo::CreateNew () const
{ {
BYTE *mem = (BYTE *)Malloc (SizeOf); BYTE *mem = (BYTE *)M_Malloc (SizeOf);
ConstructNative (mem); ConstructNative (mem);
((DObject *)mem)->SetClass (const_cast<TypeInfo *>(this)); ((DObject *)mem)->SetClass (const_cast<TypeInfo *>(this));

View file

@ -310,7 +310,7 @@ public:
void *operator new(size_t len) void *operator new(size_t len)
{ {
return Malloc(len); return M_Malloc(len);
} }
void operator delete (void *mem) void operator delete (void *mem)

View file

@ -202,7 +202,7 @@ void FCompressedFile::PostOpen ()
sizes[0] = SWAP_DWORD (sizes[0]); sizes[0] = SWAP_DWORD (sizes[0]);
sizes[1] = SWAP_DWORD (sizes[1]); sizes[1] = SWAP_DWORD (sizes[1]);
unsigned int len = sizes[0] == 0 ? sizes[1] : sizes[0]; 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); fread (m_Buffer+8, len, 1, m_File);
sizes[0] = SWAP_DWORD (sizes[0]); sizes[0] = SWAP_DWORD (sizes[0]);
sizes[1] = SWAP_DWORD (sizes[1]); 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; m_MaxBufferSize = m_MaxBufferSize ? m_MaxBufferSize * 2 : 16384;
} }
while (m_Pos + len > m_MaxBufferSize); 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) if (len == 1)
m_Buffer[m_Pos] = *(BYTE *)mem; m_Buffer[m_Pos] = *(BYTE *)mem;
@ -357,7 +357,7 @@ void FCompressedFile::Implode ()
} }
m_MaxBufferSize = m_BufferSize = ((outlen == 0) ? len : outlen); 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; m_Pos = 0;
DWORD *lens = (DWORD *)(m_Buffer); DWORD *lens = (DWORD *)(m_Buffer);
@ -384,7 +384,7 @@ void FCompressedFile::Explode ()
cprlen = BigLong(ints[0]); cprlen = BigLong(ints[0]);
expandsize = BigLong(ints[1]); expandsize = BigLong(ints[1]);
expand = (unsigned char *)Malloc (expandsize); expand = (unsigned char *)M_Malloc (expandsize);
if (cprlen) if (cprlen)
{ {
int r; int r;
@ -467,7 +467,7 @@ bool FCompressedMemFile::Open ()
m_Mode = EWriting; m_Mode = EWriting;
m_BufferSize = 0; m_BufferSize = 0;
m_MaxBufferSize = 16384; m_MaxBufferSize = 16384;
m_Buffer = (unsigned char *)Malloc (16384); m_Buffer = (unsigned char *)M_Malloc (16384);
m_Pos = 0; m_Pos = 0;
return true; return true;
} }
@ -527,7 +527,7 @@ void FCompressedMemFile::Serialize (FArchive &arc)
arc << sizes[0] << sizes[1]; arc << sizes[0] << sizes[1];
DWORD len = sizes[0] == 0 ? sizes[1] : sizes[0]; 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)[0] = SWAP_DWORD(sizes[0]);
((DWORD *)m_Buffer)[1] = SWAP_DWORD(sizes[1]); ((DWORD *)m_Buffer)[1] = SWAP_DWORD(sizes[1]);
arc.Read (m_Buffer+8, len); 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) FPNGChunkFile::FPNGChunkFile (FILE *file, DWORD id, unsigned int chunklen)
: FCompressedFile (file, EReading, true, false), m_ChunkID (id) : FCompressedFile (file, EReading, true, false), m_ChunkID (id)
{ {
m_Buffer = (byte *)Malloc (chunklen); m_Buffer = (byte *)M_Malloc (chunklen);
m_BufferSize = chunklen; m_BufferSize = chunklen;
fread (m_Buffer, chunklen, 1, m_File); fread (m_Buffer, chunklen, 1, m_File);
// Skip the CRC for now. Maybe later it will be used. // 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) if (m_ObjectCount >= m_MaxObjectCount)
{ {
m_MaxObjectCount = m_MaxObjectCount ? m_MaxObjectCount * 2 : 1024; 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++) for (i = m_ObjectCount; i < m_MaxObjectCount; i++)
{ {
m_ObjectMap[i].hashNext = ~0; m_ObjectMap[i].hashNext = ~0;

View file

@ -2138,7 +2138,7 @@ void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf)
ptrdiff_t body = demobodyspot - demobuffer; ptrdiff_t body = demobodyspot - demobuffer;
// [RH] Allocate more space for the demo // [RH] Allocate more space for the demo
maxdemosize += 0x20000; maxdemosize += 0x20000;
demobuffer = (byte *)Realloc (demobuffer, maxdemosize); demobuffer = (byte *)M_Realloc (demobuffer, maxdemosize);
demo_p = demobuffer + pos; demo_p = demobuffer + pos;
lenspot = demobuffer + spot; lenspot = demobuffer + spot;
democompspot = demobuffer + comp; democompspot = demobuffer + comp;
@ -2164,7 +2164,7 @@ void G_RecordDemo (char* name)
maxdemosize = atoi(v)*1024; maxdemosize = atoi(v)*1024;
if (maxdemosize < 0x20000) if (maxdemosize < 0x20000)
maxdemosize = 0x20000; maxdemosize = 0x20000;
demobuffer = (byte *)Malloc (maxdemosize); demobuffer = (byte *)M_Malloc (maxdemosize);
demorecording = true; demorecording = true;
} }

View file

@ -537,7 +537,7 @@ static void G_DoParseMapInfo (int lump)
if (levelindex == -1) if (levelindex == -1)
{ {
levelindex = numwadlevelinfos++; 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; levelinfo = wadlevelinfos + levelindex;
memcpy (levelinfo, &defaultinfo, sizeof(*levelinfo)); memcpy (levelinfo, &defaultinfo, sizeof(*levelinfo));
@ -602,7 +602,7 @@ static void G_DoParseMapInfo (int lump)
if (clusterindex == -1) if (clusterindex == -1)
{ {
clusterindex = numwadclusterinfos++; 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; clusterinfo = wadclusterinfos + clusterindex;
} }
else else
@ -836,7 +836,7 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
if (FindWadClusterInfo (sc_Number) == -1) if (FindWadClusterInfo (sc_Number) == -1)
{ {
int clusterindex = numwadclusterinfos++; 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; clusterinfo = wadclusterinfos + clusterindex;
memset (clusterinfo, 0, sizeof(cluster_info_t)); memset (clusterinfo, 0, sizeof(cluster_info_t));
clusterinfo->cluster = sc_Number; clusterinfo->cluster = sc_Number;

View file

@ -41,18 +41,19 @@
// except they bomb out with an error requester // except they bomb out with an error requester
// when they can't get the memory. // when they can't get the memory.
void *Malloc (size_t size); void *M_Malloc (size_t size);
void *Calloc (size_t num, size_t size); void *M_Calloc (size_t num, size_t size);
void *Realloc (void *memblock, size_t size); void *M_Realloc (void *memblock, size_t size);
#else #else
#include <stdlib.h> #include <stdlib.h>
#include <crtdbg.h> #include <crtdbg.h>
inline void *Malloc(size_t size) { return malloc (size); } #define M_Malloc(size) malloc(size)
inline void *Calloc(size_t num, size_t size) { return calloc (num, size); } #define M_Calloc(num, size) calloc(num, size)
inline void *Realloc(void *memblock, size_t size) { return realloc (memblock, size); } #define M_Realloc(memblock, size) realloc(memblock, size)
#endif #endif
#endif //__M_ALLOC_H__ #endif //__M_ALLOC_H__

View file

@ -182,7 +182,7 @@ void M_FindResponseFile (void)
if (argc != 0) 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 *); argv[i] = (char *)argv + argc*sizeof(char *);
ParseCommandLine (file, NULL, argv+i); ParseCommandLine (file, NULL, argv+i);

View file

@ -82,45 +82,22 @@ private:
static bool Inited; static bool Inited;
#ifndef __GNUC__ #ifndef __GNUC__
template<> friend bool NeedsDestructor<MainName> () { return true; }
template<> friend void CopyForTArray<MainName> (MainName &dst, MainName &src) template<> friend void CopyForTArray<MainName> (MainName &dst, MainName &src)
{ {
dst.NextHash = src.NextHash; dst.NextHash = src.NextHash;
CopyForTArray (dst.Text, src.Text); CopyForTArray (dst.Text, src.Text);
} }
template<> friend void ConstructInTArray<MainName> (MainName *dst, const MainName &src)
{
new (dst) FName::MainName(src);
}
template<> friend void ConstructEmptyInTArray<MainName> (MainName *dst)
{
new (dst) FName::MainName;
}
#else #else
template<class MainName> friend inline bool NeedsDestructor ();
template<class MainName> friend inline void CopyForTArray (MainName &dst, MainName &src); template<class MainName> friend inline void CopyForTArray (MainName &dst, MainName &src);
template<class MainName> friend inline void ConstructInTArray (MainName *dst, const MainName &src);
template<class MainName> friend inline void ConstructEmptyInTArray (MainName *dst);
#endif #endif
}; };
#ifdef __GNUC__ #ifdef __GNUC__
template<> inline bool NeedsDestructor<FName::MainName> () { return true; }
template<> inline void CopyForTArray<FName::MainName> (FName::MainName &dst, FName::MainName &src) template<> inline void CopyForTArray<FName::MainName> (FName::MainName &dst, FName::MainName &src)
{ {
dst.NextHash = src.NextHash; dst.NextHash = src.NextHash;
CopyForTArray (dst.Text, src.Text); CopyForTArray (dst.Text, src.Text);
} }
template<> inline void ConstructInTArray<FName::MainName> (FName::MainName *dst, const FName::MainName &src)
{
new (dst) FName::MainName(src);
}
template<> inline void ConstructEmptyInTArray<FName::MainName> (FName::MainName *dst)
{
new (dst) FName::MainName;
}
#endif #endif
#endif #endif

View file

@ -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_MovePolyobj (int num, int x, int y);
BOOL PO_RotatePolyobj (int num, angle_t angle); BOOL PO_RotatePolyobj (int num, angle_t angle);
void PO_Init (); void PO_Init ();
void PO_DeInit ();
BOOL PO_Busy (int polyobj); BOOL PO_Busy (int polyobj);
// //

View file

@ -4260,7 +4260,7 @@ msecnode_t *P_GetSecnode()
} }
else else
{ {
node = (msecnode_t *)Malloc (sizeof(*node)); node = (msecnode_t *)M_Malloc (sizeof(*node));
} }
return node; return node;
} }

View file

@ -2853,6 +2853,12 @@ void P_FreeLevelData ()
delete[] PolyBlockMap; delete[] PolyBlockMap;
PolyBlockMap = NULL; PolyBlockMap = NULL;
} }
po_NumPolyobjs = 0;
if (polyobjs != NULL)
{
delete[] polyobjs;
polyobjs = NULL;
}
if (rejectmatrix != NULL) if (rejectmatrix != NULL)
{ {
delete[] rejectmatrix; delete[] rejectmatrix;
@ -2951,7 +2957,6 @@ void P_SetupLevel (char *lumpname, int position)
// [RH] clear out the mid-screen message // [RH] clear out the mid-screen message
C_MidPrint (NULL); C_MidPrint (NULL);
PolyBlockMap = NULL;
// Free all level data from the previous map // Free all level data from the previous map
P_FreeLevelData (); P_FreeLevelData ();
@ -3181,8 +3186,6 @@ void P_SetupLevel (char *lumpname, int position)
for (i = 0; i < BODYQUESIZE; i++) for (i = 0; i < BODYQUESIZE; i++)
bodyque[i] = NULL; bodyque[i] = NULL;
PO_DeInit (); // Flush polyobjs from previous map
deathmatchstarts.Clear (); deathmatchstarts.Clear ();
if (!buildmap) if (!buildmap)

View file

@ -461,7 +461,7 @@ static void ParseAnim (bool istex)
sink.Countdown = frames[0].SpeedMin; sink.Countdown = frames[0].SpeedMin;
sink.NumFrames = frames.Size(); 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; *newAnim = sink;
for (i = 0; i < frames.Size(); ++i) for (i = 0; i < frames.Size(); ++i)
@ -471,7 +471,7 @@ static void ParseAnim (bool istex)
} }
else else
{ {
newAnim = (FAnimDef *)Malloc (sizeof(FAnimDef)); newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
*newAnim = sink; *newAnim = sink;
} }
@ -588,7 +588,7 @@ void P_InitPicAnims (void)
anim.Frames[0].FramePic = anim.BasePic; anim.Frames[0].FramePic = anim.BasePic;
anim.Countdown = anim.Frames[0].SpeedMin - 1; anim.Countdown = anim.Frames[0].SpeedMin - 1;
newAnim = (FAnimDef *)Malloc (sizeof(FAnimDef)); newAnim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
*newAnim = anim; *newAnim = anim;
Anims.Push (newAnim); Anims.Push (newAnim);
} }
@ -600,7 +600,7 @@ void P_InitPicAnims (void)
void P_AddSimpleAnim (int picnum, int animcount, int animtype, int animspeed) 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->bUniqueFrames = false;
anim->CurFrame = 0; anim->CurFrame = 0;
anim->BasePic = picnum; anim->BasePic = picnum;

View file

@ -149,8 +149,8 @@ void P_InitSwitchList ()
((gameinfo.maxSwitch & ~15) == (list_p[18] & ~15)) && ((gameinfo.maxSwitch & ~15) == (list_p[18] & ~15)) &&
TexMan.CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags) >= 0) TexMan.CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags) >= 0)
{ {
def1 = (FSwitchDef *)Malloc (sizeof(FSwitchDef)); def1 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
def2 = (FSwitchDef *)Malloc (sizeof(FSwitchDef)); def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
def1->PreTexture = def2->u.Textures[2] = TexMan.CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags); 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); def2->PreTexture = def1->u.Textures[2] = TexMan.CheckForTexture (list_p + 9, FTexture::TEX_Wall, texflags);
def1->Sound = def2->Sound = 0; def1->Sound = def2->Sound = 0;
@ -300,7 +300,7 @@ void P_ProcessSwitchDef ()
// it to the original texture without doing anything interesting // it to the original texture without doing anything interesting
if (def2 == NULL) if (def2 == NULL)
{ {
def2 = (FSwitchDef *)Malloc (sizeof(FSwitchDef)); def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
def2->Sound = def1->Sound; def2->Sound = def1->Sound;
def2->NumFrames = 1; def2->NumFrames = 1;
def2->u.Times[0] = 0; def2->u.Times[0] = 0;
@ -399,7 +399,7 @@ FSwitchDef *ParseSwitchDef (bool ignoreBad)
{ {
return NULL; 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->Sound = sound;
def->NumFrames = numframes; def->NumFrames = numframes;
memcpy (&def->u.Times[0], times, numframes * 4); memcpy (&def->u.Times[0], times, numframes * 4);

View file

@ -268,7 +268,7 @@ void P_InitTerrainTypes ()
int size; int size;
size = (TexMan.NumTextures()+1)*sizeof(byte); size = (TexMan.NumTextures()+1)*sizeof(byte);
TerrainTypes = (byte *)Malloc (size); TerrainTypes = (byte *)M_Malloc (size);
memset (TerrainTypes, 0, size); memset (TerrainTypes, 0, size);
MakeDefaultTerrain (); MakeDefaultTerrain ();

View file

@ -1541,27 +1541,6 @@ void PO_Init (void)
KillSegLists (); 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 // PO_Busy

View file

@ -119,7 +119,7 @@ void R_ClearDrawSegs (void)
if (drawsegs == NULL) if (drawsegs == NULL)
{ {
MaxDrawSegs = 256; // [RH] Default. Increased as needed. 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; FirstInterestingDrawseg = 0;
InterestingDrawsegs.Clear (); InterestingDrawsegs.Clear ();

View file

@ -308,7 +308,7 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
int height; int height;
int width; int width;
foo = (patch_t *)Malloc (data.GetLength()); foo = (patch_t *)M_Malloc (data.GetLength());
data.Seek (-4, SEEK_CUR); data.Seek (-4, SEEK_CUR);
data.Read (foo, data.GetLength()); data.Read (foo, data.GetLength());
@ -823,7 +823,7 @@ FTexture::Span **FTexture::CreateSpans (const BYTE *pixels) const
if (!bMasked) if (!bMasked)
{ // Texture does not have holes, so it can use a simpler span structure { // 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]; span = (Span *)&spans[Width];
for (int x = 0; x < Width; ++x) for (int x = 0; x < Width; ++x)
{ {
@ -867,7 +867,7 @@ FTexture::Span **FTexture::CreateSpans (const BYTE *pixels) const
} }
// Allocate space for the spans // 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 // Fill in the spans
for (x = 0, span = (Span *)&spans[numcols], data_p = pixels; x < numcols; ++x) for (x = 0, span = (Span *)&spans[numcols], data_p = pixels; x < numcols; ++x)
@ -1271,7 +1271,7 @@ void FPatchTexture::MakeTexture ()
} }
// Create the spans // 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); spanstuffer = (Span *)((BYTE *)Spans + sizeof(Span*)*Width);
warned = false; warned = false;
@ -1393,7 +1393,7 @@ void FPatchTexture::HackHack (int newheight)
} }
// Create the spans // 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]; Span *span = (Span *)&Spans[Width];

View file

@ -474,7 +474,7 @@ static visplane_t *new_visplane (unsigned hash)
if (check == NULL) 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]; check->bottom = &check->top[MAXWIDTH+2];
} }
else if (NULL == (freetail = freetail->next)) else if (NULL == (freetail = freetail->next))

View file

@ -1104,7 +1104,7 @@ void R_CheckDrawSegs ()
{ // [RH] Grab some more drawsegs { // [RH] Grab some more drawsegs
size_t newdrawsegs = MaxDrawSegs ? MaxDrawSegs*2 : 32; size_t newdrawsegs = MaxDrawSegs ? MaxDrawSegs*2 : 32;
ptrdiff_t firstofs = firstdrawseg - drawsegs; 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; firstdrawseg = drawsegs + firstofs;
ds_p = drawsegs + MaxDrawSegs; ds_p = drawsegs + MaxDrawSegs;
MaxDrawSegs = newdrawsegs; MaxDrawSegs = newdrawsegs;
@ -1125,7 +1125,7 @@ void R_CheckOpenings (size_t need)
do do
maxopenings = maxopenings ? maxopenings*2 : 16384; maxopenings = maxopenings ? maxopenings*2 : 16384;
while (need > maxopenings); 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); DPrintf ("MaxOpenings increased to %u\n", maxopenings);
} }
} }

View file

@ -808,7 +808,7 @@ vissprite_t *R_NewVisSprite (void)
ptrdiff_t prevvisspritenum = vissprite_p - vissprites; ptrdiff_t prevvisspritenum = vissprite_p - vissprites;
MaxVisSprites = MaxVisSprites ? MaxVisSprites * 2 : 128; 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]; lastvissprite = &vissprites[MaxVisSprites];
firstvissprite = &vissprites[firstvisspritenum]; firstvissprite = &vissprites[firstvisspritenum];
vissprite_p = &vissprites[prevvisspritenum]; vissprite_p = &vissprites[prevvisspritenum];

View file

@ -946,7 +946,7 @@ static void S_AddSNDINFO (int lump)
SC_MustGetString(); SC_MustGetString();
FString musname (sc_String); FString musname (sc_String);
SC_MustGetFloat(); SC_MustGetFloat();
FMusicVolume *mv = (FMusicVolume *)Malloc (sizeof(*mv) + musname.Len()); FMusicVolume *mv = (FMusicVolume *)M_Malloc (sizeof(*mv) + musname.Len());
mv->Volume = sc_Float; mv->Volume = sc_Float;
strcpy (mv->MusicName, musname); strcpy (mv->MusicName, musname);
mv->Next = MusicVolumes; mv->Next = MusicVolumes;

View file

@ -648,7 +648,7 @@ void S_ParseSndSeq (int levellump)
static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, const TArray<DWORD> &ScriptTemp) static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, const TArray<DWORD> &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]->SeqName = seqname;
Sequences[curseq]->Slot = slot; Sequences[curseq]->Slot = slot;
Sequences[curseq]->StopSound = stopsound; Sequences[curseq]->StopSound = stopsound;

View file

@ -258,7 +258,7 @@ void FStringTable::LoadLanguage (int lumpnum, DWORD code, bool exactMatch, int p
} }
if (entry == NULL || cmpval > 0) 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; entry->Next = *pentry;
*pentry = entry; *pentry = entry;
strcpy (entry->String, strText.GetChars()); strcpy (entry->String, strText.GetChars());
@ -380,7 +380,7 @@ void FStringTable::SetString (const char *name, const char *newString)
size_t namelen = strlen (name); size_t namelen = strlen (name);
// Create a new string entry // 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->String, newString);
strcpy (entry->Name = entry->String + newlen + 1, name); strcpy (entry->Name = entry->String + newlen + 1, name);
entry->PassNum = 0; entry->PassNum = 0;

View file

@ -36,14 +36,11 @@
#define __TARRAY_H__ #define __TARRAY_H__
#include <stdlib.h> #include <stdlib.h>
#include <assert.h>
#include <new>
#include "m_alloc.h" #include "m_alloc.h"
// Specialize this function for any type that needs to have its destructor called.
template<class T>
bool NeedsDestructor ()
{
return false;
}
// This function is called once for each entry in the TArray after it grows. // 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 // The old entries will be immediately freed afterwards, so if they need to
@ -51,11 +48,8 @@ bool NeedsDestructor ()
template<class T> template<class T>
void CopyForTArray (T &dst, T &src) void CopyForTArray (T &dst, T &src)
{ {
dst = src; ::new((void*)&dst) T(src);
if (NeedsDestructor<T>()) src.~T();
{
src.~T();
}
} }
// This function is called by Push to copy the the element to an unconstructed // 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<class T> template<class T>
void ConstructInTArray (T *dst, const T &src) void ConstructInTArray (T *dst, const T &src)
{ {
//new (dst) T(src); ::new((void*)dst) T(src);
*dst = src;
} }
// This function is much like the above function, except it is called when // 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<class T> template<class T>
void ConstructEmptyInTArray (T *dst) void ConstructEmptyInTArray (T *dst)
{ {
::new((void*)dst) T;
} }
template <class T> template <class T>
@ -89,7 +83,7 @@ public:
{ {
Most = max; Most = max;
Count = 0; Count = 0;
Array = (T *)Malloc (sizeof(T)*max); Array = (T *)M_Malloc (sizeof(T)*max);
} }
TArray (const TArray<T> &other) TArray (const TArray<T> &other)
{ {
@ -101,7 +95,10 @@ public:
{ {
if (Array != NULL) if (Array != NULL)
{ {
DoDelete (0, Count-1); if (Count > 0)
{
DoDelete (0, Count-1);
}
free (Array); free (Array);
} }
DoCopy (other); DoCopy (other);
@ -112,8 +109,14 @@ public:
{ {
if (Array) if (Array)
{ {
DoDelete (0, Count-1); if (Count > 0)
{
DoDelete (0, Count-1);
}
free (Array); free (Array);
Array = NULL;
Count = 0;
Most = 0;
} }
} }
T &operator[] (unsigned int index) const T &operator[] (unsigned int index) const
@ -142,11 +145,43 @@ public:
} }
void Delete (unsigned int index) 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) if (index < Count)
{
for (unsigned int i = index; i < Count - 1; ++i)
{
Array[i] = Array[i+1];
}
Count--; 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 () void ShrinkToFit ()
{ {
@ -186,12 +221,9 @@ public:
{ {
Grow (amount - Count); Grow (amount - Count);
} }
if (NeedsDestructor<T>()) for (unsigned int i = Count; i < amount; ++i)
{ {
for (unsigned int i = Count; i < amount; ++i) ConstructEmptyInTArray (&Array[i]);
{
ConstructEmptyInTArray (&Array[i]);
}
} }
Count = amount; Count = amount;
} }
@ -217,8 +249,11 @@ public:
} }
void Clear () void Clear ()
{ {
DoDelete (0, Count-1); if (Count > 0)
Count = 0; {
DoDelete (0, Count-1);
Count = 0;
}
} }
private: private:
T *Array; T *Array;
@ -230,7 +265,7 @@ private:
Most = Count = other.Count; Most = Count = other.Count;
if (Count != 0) if (Count != 0)
{ {
Array = (T *)Malloc (sizeof(T)*Most); Array = (T *)M_Malloc (sizeof(T)*Most);
for (unsigned int i = 0; i < Count; ++i) for (unsigned int i = 0; i < Count; ++i)
{ {
Array[i] = other.Array[i]; Array[i] = other.Array[i];
@ -244,7 +279,7 @@ private:
void DoResize () 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) for (unsigned int i = 0; i < Count; ++i)
{ {
CopyForTArray (newarray[i], Array[i]); CopyForTArray (newarray[i], Array[i]);
@ -255,12 +290,10 @@ private:
void DoDelete (unsigned int first, unsigned int last) void DoDelete (unsigned int first, unsigned int last)
{ {
if (NeedsDestructor<T>()) 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();
}
} }
} }
}; };

View file

@ -256,7 +256,7 @@ static DWORD Zip_FindCentralDir(FileReader * fin)
FileSize = fin->Tell(); FileSize = fin->Tell();
uMaxBack = MIN<DWORD>(0xffff, FileSize); uMaxBack = MIN<DWORD>(0xffff, FileSize);
buf = (unsigned char*)Malloc(BUFREADCOMMENT+4); buf = (unsigned char*)M_Malloc(BUFREADCOMMENT+4);
if (buf == NULL) return 0; if (buf == NULL) return 0;
uBackRead = 4; 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)); BloodCrypt (lumps, header.rff.DirOfs, header.rff.NumLumps * sizeof(rfflump_t));
NumLumps += header.rff.NumLumps; NumLumps += header.rff.NumLumps;
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
lump_p = &LumpInfo[startlump]; lump_p = &LumpInfo[startlump];
for (i = 0, rff_p = lumps; i < header.rff.NumLumps; ++i, ++rff_p) 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); pos = sizeof(grpinfo_t) + header.grp.NumLumps * sizeof(grplump_t);
NumLumps += header.grp.NumLumps; NumLumps += header.grp.NumLumps;
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
lump_p = &LumpInfo[startlump]; lump_p = &LumpInfo[startlump];
for (i = 0, grp_p = lumps; i < header.grp.NumLumps; ++i, ++grp_p) 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); NumLumps += LittleShort(info.wEntryCount);
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
lump_p = &LumpInfo[startlump]; lump_p = &LumpInfo[startlump];
// Load the entire central directory. Too bad that this contains variable length entries... // 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 // Resize the lump record array to its actual size
NumLumps -= skipped; NumLumps -= skipped;
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
// Entries in Zips are sorted alphabetically. // Entries in Zips are sorted alphabetically.
qsort(LumpInfo + startlump, NumLumps - startlump, sizeof(LumpRecord), lumpcmp); 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] != ZIP_ID &&
(header.magic[0] != GRP_ID_0 || header.magic[1] != GRP_ID_1 || header.magic[2] != GRP_ID_2)) (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]; lump_p = &LumpInfo[startlump];
for (i = startlump; i < (unsigned)NumLumps; i++, lump_p++, fileinfo++) 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->FirstLump = startlump;
wadinfo->LastLump = NumLumps - 1; wadinfo->LastLump = NumLumps - 1;
Wads = (WadFileRecord **)Realloc (Wads, (++NumWads)*sizeof(WadFileRecord*)); Wads = (WadFileRecord **)M_Realloc (Wads, (++NumWads)*sizeof(WadFileRecord*));
Wads[NumWads-1] = wadinfo; Wads[NumWads-1] = wadinfo;
// [RH] Put the Strife Teaser voices into the voices namespace // [RH] Put the Strife Teaser voices into the voices namespace
@ -1153,7 +1153,7 @@ void FWadCollection::ScanForFlatHack (int startlump)
} }
} }
++NumLumps; ++NumLumps;
LumpInfo = (LumpRecord *)Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
for (; i > j; --i) for (; i > j; --i)
{ {
LumpInfo[i+1] = LumpInfo[i]; LumpInfo[i+1] = LumpInfo[i];
@ -1374,7 +1374,7 @@ int FWadCollection::MergeLumps (const char *start, const char *end, int space)
if (newlumps) if (newlumps)
{ {
if (size_t(oldlumps + newlumps) >= NumLumps) 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); memcpy (LumpInfo + oldlumps, newlumpinfos, sizeof(LumpRecord) * newlumps);
markerpos = oldlumps; markerpos = oldlumps;

View file

@ -646,11 +646,12 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
SetUnhandledExceptionFilter (CatchAllExceptions); SetUnhandledExceptionFilter (CatchAllExceptions);
} }
#ifdef _DEBUG #if defined(_DEBUG) && defined(_MSC_VER)
// Uncomment this line to make the Visual C++ CRT check the heap before // 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 // every allocation and deallocation. This will be slow, but it can be a
// great help in finding problem areas. // great help in finding problem areas.
//_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF); //_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF);
_CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF);
#endif #endif
DoMain (hInstance); DoMain (hInstance);

View file

@ -161,8 +161,6 @@ protected:
char *Chars; char *Chars;
#ifndef __GNUC__ #ifndef __GNUC__
template<> friend bool NeedsDestructor<FString> () { return true; }
template<> friend void CopyForTArray<FString> (FString &dst, FString &src) template<> friend void CopyForTArray<FString> (FString &dst, FString &src)
{ {
// When a TArray is resized, we just need to update the Owner, because // 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; ((FString::StringHeader *)(chars - sizeof(FString::StringHeader)))->Owner = &dst;
} }
} }
template<> friend void ConstructInTArray<FString> (FString *dst, const FString &src)
{
new (dst) FString(src);
}
template<> friend void ConstructEmptyInTArray<FString> (FString *dst)
{
new (dst) FString;
}
#else #else
template<class FString> friend inline void CopyForTArray (FString &dst, FString &src); template<class FString> friend inline void CopyForTArray (FString &dst, FString &src);
template<class FString> friend inline void ConstructInTArray (FString *dst, const FString &src);
template<class FString> friend inline void ConstructEmptyInTArray (FString *dst);
#endif #endif
private: private:
@ -201,7 +189,6 @@ private:
}; };
#ifdef __GNUC__ #ifdef __GNUC__
template<> inline bool NeedsDestructor<FString> () { return true; }
template<> inline void CopyForTArray<FString> (FString &dst, FString &src) template<> inline void CopyForTArray<FString> (FString &dst, FString &src)
{ {
// When a TArray is resized, we just need to update the Owner, because // When a TArray is resized, we just need to update the Owner, because
@ -215,14 +202,6 @@ template<> inline void CopyForTArray<FString> (FString &dst, FString &src)
((FString::StringHeader *)(chars - sizeof(FString::StringHeader)))->Owner = &dst; ((FString::StringHeader *)(chars - sizeof(FString::StringHeader)))->Owner = &dst;
} }
} }
template<> inline void ConstructInTArray<FString> (FString *dst, const FString &src)
{
new (dst) FString(src);
}
template<> inline void ConstructEmptyInTArray<FString> (FString *dst)
{
new (dst) FString;
}
#endif #endif
namespace StringFormat namespace StringFormat

View file

@ -31,7 +31,7 @@ struct FString::Pool
char *Realloc (char *chars, size_t newlen); char *Realloc (char *chars, size_t newlen);
void Free (char *chars); void Free (char *chars);
void MergeFreeBlocks (StringHeader *block); void MergeFreeBlocks (StringHeader *block);
void CollectGarbage (bool noGenerations); void CollectGarbage ();
bool BigEnough (size_t len) const; bool BigEnough (size_t len) const;
size_t RoundLen (size_t len) const; size_t RoundLen (size_t len) const;
@ -40,8 +40,6 @@ struct FString::Pool
char *PoolData; char *PoolData;
char *MaxAlloc; char *MaxAlloc;
StringHeader *NextAlloc; StringHeader *NextAlloc;
StringHeader *GarbageStart;
int GenerationNum;
}; };
// The PoolGroup does not get a constructor, because there is no way to // 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)) if (best->BigEnough (len))
{ {
best->CollectGarbage (false); best->CollectGarbage ();
mem = best->Alloc (owner, len); 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 // Move the pool to the front of the list
*bestprev = best->Next; *bestprev = best->Next;
best->Next = Pools; best->Next = Pools;
@ -151,7 +144,10 @@ char *FString::PoolGroup::Realloc (FString *owner, char *chars, size_t newlen)
void FString::PoolGroup::Free (char *chars) void FString::PoolGroup::Free (char *chars)
{ {
Pool *pool = FindPool (chars); Pool *pool = FindPool (chars);
pool->Free (chars); if (pool != NULL)
{
pool->Free (chars);
}
} }
FString::Pool *FString::PoolGroup::FindPool (char *chars) const FString::Pool *FString::PoolGroup::FindPool (char *chars) const
@ -187,8 +183,6 @@ FString::Pool::Pool (size_t minSize)
NextAlloc = (StringHeader *)PoolData; NextAlloc = (StringHeader *)PoolData;
NextAlloc->Owner = NULL; NextAlloc->Owner = NULL;
NextAlloc->Len = minSize; NextAlloc->Len = minSize;
GarbageStart = NextAlloc;
GenerationNum = 0;
} }
FString::Pool::~Pool () FString::Pool::~Pool ()
@ -199,19 +193,19 @@ FString::Pool::~Pool ()
// all the strings stored in it. So we need to walk through the pool // all the strings stored in it. So we need to walk through the pool
// and make any owned strings un-owned. // and make any owned strings un-owned.
StringHeader *str; StringHeader *str;
StringHeader *laststr;
for (str = (StringHeader *)PoolData; str < NextAlloc; ) for (str = (StringHeader *)PoolData; str < NextAlloc; )
{ {
if (str->Owner != NULL) if (str->Owner != NULL)
{ {
str->Owner->Chars = NULL; FString *owner = str->Owner;
str->Owner = NULL; assert (owner->Chars == (char *)str + sizeof(StringHeader));
str = (StringHeader *)((char *)str + RoundLen(str->Len)); Free ((char *)str + sizeof(StringHeader));
} owner->Chars = "";
else
{
str = (StringHeader *)((char *)str + str->Len);
} }
laststr = str;
str = (StringHeader *)((char *)str + str->Len);
} }
delete[] PoolData; delete[] PoolData;
@ -308,6 +302,21 @@ char *FString::Pool::Realloc (char *chars, size_t newlen)
void FString::Pool::Free (char *chars) 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)); StringHeader *head = (StringHeader *)(chars - sizeof(StringHeader));
size_t truelen = RoundLen (head->Len); size_t truelen = RoundLen (head->Len);
@ -316,6 +325,25 @@ void FString::Pool::Free (char *chars)
head->Owner = NULL; head->Owner = NULL;
head->Len = truelen; head->Len = truelen;
MergeFreeBlocks (head); 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) 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 this chain of blocks meets up with the free space, then they can join up with it.
if (block == NextAlloc) if (block == NextAlloc)
{ {
if (GarbageStart == NextAlloc)
{
GarbageStart = head;
}
NextAlloc = head; NextAlloc = head;
head->Len = MaxAlloc - (char *)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); 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 // 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. // the first two generations will not be collected unless noGenerations is set true.
if (noGenerations)
{
GarbageStart = (StringHeader *)PoolData;
GenerationNum = 0;
}
StringHeader *moveto, *movefrom; StringHeader *moveto, *movefrom;
moveto = movefrom = GarbageStart; moveto = movefrom = (StringHeader *)PoolData;
while (movefrom < NextAlloc) while (movefrom < NextAlloc)
{ {
@ -397,11 +415,6 @@ void FString::Pool::CollectGarbage (bool noGenerations)
} }
else if (FreeSpace != 0) else if (FreeSpace != 0)
FreeSpace = FreeSpace; FreeSpace = FreeSpace;
if (++GenerationNum <= 3)
{
GarbageStart = moveto;
}
} }
#else #else
char *FString::PoolGroup::Alloc (FString *owner, size_t len) char *FString::PoolGroup::Alloc (FString *owner, size_t len)