Fix memory leaks + prevent potential segfault when saving/loading games (#160)

This commit is contained in:
jdgleaver 2021-11-04 18:27:27 +00:00 committed by GitHub
parent cb13c1561d
commit e8ebfe780f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 114 additions and 45 deletions

View File

@ -501,6 +501,16 @@ void I_UpdateSoundParams (int handle, int vol, int sep, int pitch)
void I_ShutdownSound(void)
{
int i;
for(i = 0; i < NUMSFX; i++)
{
if (!S_sfx[i].link)
{
free(S_sfx[i].data);
S_sfx[i].data = NULL;
}
}
}

View File

@ -1481,16 +1481,20 @@ void D_DoomDeinit(void)
lprintf(LO_INFO,"D_DoomDeinit:\n");
//Deinit
M_QuitDOOM(0);
Z_Close();
#ifdef HAVE_NET
D_QuitNetGame();
I_ShutdownNetwork();
#endif
M_SaveDefaults ();
W_Exit();
W_ReleaseAllWads();
U_FreeMapInfo();
I_ShutdownSound();
I_ShutdownMusic();
V_FreeScreens();
V_DestroyUnusedTrueColorPalettes();
R_FlushAllPatches();
P_Deinit();
Z_Close();
}
//

View File

@ -160,6 +160,8 @@ int wipe_StartScreen(void)
wipe_scr_start.height = SCREENHEIGHT;
wipe_scr_start.not_on_heap = FALSE;
V_AllocScreen(&wipe_scr_start);
if (&screens[SRC_SCR] != &wipe_scr_start)
V_FreeScreen(&screens[SRC_SCR]);
screens[SRC_SCR] = wipe_scr_start;
V_CopyRect(0, 0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0, SRC_SCR, VPT_NONE ); // Copy start screen to buffer
return 0;
@ -170,6 +172,8 @@ int wipe_EndScreen(void)
wipe_scr_end.height = SCREENHEIGHT;
wipe_scr_end.not_on_heap = FALSE;
V_AllocScreen(&wipe_scr_end);
if (&screens[DEST_SCR] != &wipe_scr_end)
V_FreeScreen(&screens[DEST_SCR]);
screens[DEST_SCR] = wipe_scr_end;
V_CopyRect(0, 0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0, DEST_SCR, VPT_NONE); // Copy end screen to buffer
V_CopyRect(0, 0, SRC_SCR, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0 , VPT_NONE); // restore start screen

View File

@ -383,13 +383,19 @@ void P_ArchiveThinkers (void)
for (i = 0; i < numsectors; i++)
{
mobj_t *target = sectors[i].soundtarget;
// Fix crash on reload when a soundtarget points to a removed corpse
// (prboom bug #1590350)
if (target && target->thinker.function == P_MobjThinker)
target = (mobj_t *) target->thinker.prev;
else
target = NULL;
memcpy(save_p, &target, sizeof target);
if (target)
memcpy(save_p, &target, sizeof target);
else
memset(save_p, 0, sizeof target);
save_p += sizeof target;
}
}
@ -419,9 +425,9 @@ static void P_SetNewTarget(mobj_t **mop, mobj_t *targ)
// safely casts them back to int.
static int P_GetMobj(mobj_t* mi, size_t s)
{
size_t i = (size_t)mi;
uintptr_t i = (uintptr_t)mi;
if (i >= s) I_Error("Corrupt savegame");
return i;
return (int)i;
}
void P_UnArchiveThinkers (void)
@ -549,8 +555,14 @@ void P_UnArchiveThinkers (void)
mobj_t *target;
memcpy(&target, save_p, sizeof target);
save_p += sizeof target;
// Must verify soundtarget. See P_ArchiveThinkers.
P_SetNewTarget(&sectors[i].soundtarget, mobj_p[P_GetMobj(target,size)]);
// Check if 'saved' soundtarget pointer was NULL
// or otherwise invalid
if (!target || P_GetMobj(target,size) >= size)
sectors[i].soundtarget = 0;
else
P_SetNewTarget(&sectors[i].soundtarget, mobj_p[P_GetMobj(target,size)]);
}
}

View File

@ -58,26 +58,26 @@
// Store VERTEXES, LINEDEFS, SIDEDEFS, etc.
//
int numvertexes;
vertex_t *vertexes;
int numvertexes = 0;
vertex_t *vertexes = NULL;
int numsegs;
seg_t *segs;
int numsegs = 0;
seg_t *segs = NULL;
int numsectors;
sector_t *sectors;
int numsectors = 0;
sector_t *sectors = NULL;
int numsubsectors;
subsector_t *subsectors;
int numsubsectors = 0;
subsector_t *subsectors = NULL;
int numnodes;
node_t *nodes;
int numnodes = 0;
node_t *nodes = NULL;
int numlines;
line_t *lines;
int numlines = 0;
line_t *lines = NULL;
int numsides;
side_t *sides;
int numsides = 0;
side_t *sides = NULL;
////////////////////////////////////////////////////////////////////////////////////////////
@ -1918,3 +1918,35 @@ void P_Init (void)
P_InitPicAnims();
R_InitSprites(sprnames);
}
/*
*
=================
=
= P_Deinit
=
=================
*/
void P_Deinit(void)
{
Z_Free(vertexes);
numvertexes = 0;
Z_Free(segs);
numsegs = 0;
Z_Free(sectors);
numsectors = 0;
Z_Free(subsectors);
numsubsectors = 0;
Z_Free(nodes);
numnodes = 0;
Z_Free(lines);
numlines = 0;
Z_Free(sides);
numsides = 0;
}

View File

@ -38,6 +38,7 @@
void P_SetupLevel(int episode, int map, int playermask, skill_t skill);
void P_Init(void); /* Called by startup code. */
void P_Deinit(void);
extern const uint8_t *rejectmatrix; /* for fast sight rejection - cph - const* */

View File

@ -98,8 +98,12 @@ void R_FlushAllPatches(void) {
if (patches)
{
for (i=0; i < numlumps; i++)
{
if (patches[i].locks > 0)
I_Error("R_FlushAllPatches: patch number %i still locked",i);
if (patches[i].data)
free(patches[i].data);
}
free(patches);
patches = NULL;
}

View File

@ -495,46 +495,49 @@ void W_Init(void)
void W_Exit(void)
{
unsigned i;
for (i = 0; i < numwadfiles; i++)
unsigned i;
for (i = 0; i < numwadfiles; i++)
{
if (wadfiles[i].handle)
if (wadfiles[i].handle)
{
#ifdef MEMORY_LOW
close(wadfiles[i].handle);
#else
filestream_close(wadfiles[i].handle);
free(wadfiles[i].data);
wadfiles[i].data = NULL;
#endif
wadfiles[i].handle = NULL;
}
}
}
}
void W_ReleaseAllWads(void)
{
unsigned i;
W_DoneCache();
unsigned i;
W_DoneCache();
for(i = 0; i < numwadfiles; i++)
{
if(wadfiles[i].handle)
{
for(i = 0; i < numwadfiles; i++)
{
if(wadfiles[i].handle)
{
#ifdef MEMORY_LOW
close(wadfiles[i].handle);
close(wadfiles[i].handle);
#else
filestream_close(wadfiles[i].handle);
free(wadfiles[i].data);
free(wadfiles[i].data);
wadfiles[i].data = NULL;
#endif
wadfiles[i].handle = 0;
}
}
wadfiles[i].handle = NULL;
}
}
numwadfiles = 0;
free(wadfiles);
wadfiles = NULL;
numlumps = 0;
free(lumpinfo);
lumpinfo = NULL;
numwadfiles = 0;
free(wadfiles);
wadfiles = NULL;
numlumps = 0;
free(lumpinfo);
lumpinfo = NULL;
}
//

View File

@ -105,10 +105,9 @@ void Z_DumpHistory(char *buf)
void Z_Close(void)
{
#if 0
(free)(zonebase);
zone = rover = zonebase = NULL;
#endif
Z_FreeTags(PU_FREE, PU_MAX);
memory_size = 0;
free_memory = 0;
}
bool Z_Init(void)