fix memory leak in iter_mons_safe()

While hunting for a memory leak in object allocation--which I haven't
found yet--I discovered one in monster movement.  iter_mons_safe()
allocates an array of (monst *) pointers for the monsters on the
current level, loops over that array to call a function for each
one, then frees the array.  But if the game ends while that called
function is running, execution never returns to iter_mons_safe() so
it wasn't able to free the memory.

Since that can happen at most once per game, it wasn't a signifcant
leak.  This fixes it anyway.

There was a second issue:  make sure that iter_mons_safe() doesn't
call alloc(0) to make the temporary array for zero monsters when
there aren't any on the level.  That might not be able to happen for
monster movement but the routine is written to be more general than
just movement.  alloc(0) could confuse the MONITOR_HEAP code.  In
C89/C90 I think malloc(0) is allowed to return NULL (don't recall
for sure; maybe that was just known pre-standard behavior for some
implementations).  Null return would trigger a panic even without
MONITOR_HEAP.  Don't know about C99 and later.
This commit is contained in:
PatR
2024-01-23 23:04:06 -08:00
parent 1d165f20ee
commit 78252de3bc
4 changed files with 53 additions and 36 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 decl.h $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.351 $ */
/* NetHack 3.7 decl.h $NHDT-Date: 1706079834 2024/01/24 07:03:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.355 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2007. */
/* NetHack may be freely redistributed. See license for details. */
@@ -473,6 +473,10 @@ struct instance_globals_i {
unsigned invbufsiz;
int in_sync_perminvent;
/* mon.c */
struct monst **itermonarr; /* temporary array of all N monsters
* on the current level */
/* restore.c */
struct bucket *id_map;