From: PatR Date: Thu, 21 Sep 2017 22:30:24 +0000 (-0700) Subject: 'nulls[]' vs saving traps and fruit X-Git-Tag: NetHack-3.6.1_RC01~347 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c665d732164af9fd66a39a48fa5811576237111a;p=nethack 'nulls[]' vs saving traps and fruit It was once pointed out that static long nulls[ sizeof (struct trap) + sizeof (struct fruit) ]; should have been static long nulls[ max(sizeof (struct trap), sizeof (struct fruit)) ]; which is right, but using an array of longs to represent a null trap or null fruit doesn't handle pointers properly so replace 'nulls' with separate structs. This doesn't recover the previously wasted memory (fairly trivial since these structs are small) but does guarantee that null pointers in the relevant structs always have a valid value instead of just all bits zero. --- diff --git a/src/save.c b/src/save.c index fdbe0a22c..b907b1ad1 100644 --- a/src/save.c +++ b/src/save.c @@ -64,8 +64,6 @@ static struct save_procs { #endif }; -static long nulls[sizeof(struct trap) + sizeof(struct fruit)]; - #if defined(UNIX) || defined(VMS) || defined(__EMX__) || defined(WIN32) #define HUP if (!program_state.done_hup) #else @@ -1172,23 +1170,26 @@ register struct monst *mtmp; bwrite(fd, (genericptr_t) &minusone, sizeof(int)); } +/* save traps; ftrap is the only trap chain so the 2nd arg is superfluous */ STATIC_OVL void savetrapchn(fd, trap, mode) -register int fd, mode; +int fd; register struct trap *trap; +int mode; { + static struct trap zerotrap; register struct trap *trap2; while (trap) { trap2 = trap->ntrap; if (perform_bwrite(mode)) - bwrite(fd, (genericptr_t) trap, sizeof(struct trap)); + bwrite(fd, (genericptr_t) trap, sizeof (struct trap)); if (release_data(mode)) dealloc_trap(trap); trap = trap2; } if (perform_bwrite(mode)) - bwrite(fd, (genericptr_t) nulls, sizeof(struct trap)); + bwrite(fd, (genericptr_t) &zerotrap, sizeof zerotrap); } /* save all the fruit names and ID's; this is used only in saving whole games @@ -1198,21 +1199,22 @@ register struct trap *trap; */ void savefruitchn(fd, mode) -register int fd, mode; +int fd, mode; { + static struct fruit zerofruit; register struct fruit *f2, *f1; f1 = ffruit; while (f1) { f2 = f1->nextf; if (f1->fid >= 0 && perform_bwrite(mode)) - bwrite(fd, (genericptr_t) f1, sizeof(struct fruit)); + bwrite(fd, (genericptr_t) f1, sizeof (struct fruit)); if (release_data(mode)) dealloc_fruit(f1); f1 = f2; } if (perform_bwrite(mode)) - bwrite(fd, (genericptr_t) nulls, sizeof(struct fruit)); + bwrite(fd, (genericptr_t) &zerofruit, sizeof zerofruit); if (release_data(mode)) ffruit = 0; } @@ -1222,6 +1224,7 @@ store_plname_in_file(fd) int fd; { int plsiztmp = PL_NSIZ; + bufoff(fd); /* bwrite() before bufon() uses plain write() */ bwrite(fd, (genericptr_t) &plsiztmp, sizeof(plsiztmp));