]> granicus.if.org Git - nethack/commitdiff
'nulls[]' vs saving traps and fruit
authorPatR <rankin@nethack.org>
Thu, 21 Sep 2017 22:30:24 +0000 (15:30 -0700)
committerPatR <rankin@nethack.org>
Thu, 21 Sep 2017 22:30:24 +0000 (15:30 -0700)
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.

src/save.c

index fdbe0a22c76b30209fe8658db99a5702552cde5b..b907b1ad182d400b06f729838d6813ff5f6eb597 100644 (file)
@@ -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));