Problem freeing fight_messages

From: Ron Cole (rcole@EZY.NET)
Date: 08/29/97


OK, this is a weird one...  we wanted to be able to reload the fight messages,
so they could be changed and tested immediately.  I didn't want a big memory
leak, so, I changed load_messages() as follows and added a call to it in
do_reboot for "reload messages":

void load_messages(void)
{
  FILE *fl;
  int i, type;
  struct message_type *messages, *next;
  char chk[128];

  if (!(fl = fopen(MESS_FILE, "r"))) {
    sprintf(buf2, "Error reading combat message file %s", MESS_FILE);
    perror(buf2);
    exit(1);
  }
  for (i = 0; i < MAX_MESSAGES; i++) {
    fight_messages[i].a_type = 0;
    fight_messages[i].number_of_attacks = 0;
    messages = fight_messages[i].msg;
    while (messages) {
      if (messages->die_msg.attacker_msg)
        free(messages->die_msg.attacker_msg);
      if (messages->die_msg.victim_msg)
        free(messages->die_msg.victim_msg);
      if (messages->die_msg.room_msg)
        free(messages->die_msg.room_msg);
      if (messages->miss_msg.attacker_msg)
        free(messages->miss_msg.attacker_msg);
      if (messages->miss_msg.victim_msg)
        free(messages->miss_msg.victim_msg);
      if (messages->miss_msg.room_msg)
        free(messages->miss_msg.room_msg);
      if (messages->hit_msg.attacker_msg)
        free(messages->hit_msg.attacker_msg);
      if (messages->hit_msg.victim_msg)
        free(messages->hit_msg.victim_msg);
      if (messages->hit_msg.room_msg)
        free(messages->hit_msg.room_msg);
      if (messages->god_msg.attacker_msg)
        free(messages->god_msg.attacker_msg);
      if (messages->god_msg.victim_msg)
        free(messages->god_msg.victim_msg);  /* 2 */
      if (messages->god_msg.room_msg)
        free(messages->god_msg.room_msg);    /* 1 */
      next = messages->next;
      free(messages);
      messages = next;
    }
    fight_messages[i].msg = 0;
  }

... stock code to load the messages ...

It crashed with a segfault in libc_free on the line marked "1", when attempting
to free the last message loaded.  I determined this by stepping through with
gdb.  The message was indeed allocated and all seemed fine, no reason for it to
crash.  So, I went into the messages file and made the last message a "#" (no
message).  Now it crashes on the line marked "2".  I'm completely befuddled.  I
added a check to both of the marked lines by checking for the the last message
and not freeing it (&& fight_messages[i+1].a_type !=0), and sure enough, the
crash went away, but we now have a memory leak.  There's nothing unusual about
the way the last message is read, since there is an extra line on the messages
file ("$").  It doesn't know it's gonna be the last line when it reads it, so
nothing is done differently.

It's a Pentium system running Linux, not sure what library levels and such, but
they aren't very old.

Any ideas?

Ron


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/08/00 PST