Re: Access violation

From: Claude Belisle (cbeli@pop.agri.ch)
Date: 02/16/00


J P wrote:
<snip>

> I ru the debugger (yes my pride and joy) and I get an access violation here
> (in db.c) the (-> near the if statement is the little yellow arrow I get
> when i run the debugger heh.. cute, no?)
>
>  do {
>     fgets(tmp, READ_SIZE, fl);
>     tmp[strlen(tmp) - 1] = '\0'; /* take off the trailing \n */
>     strcat(tmp, "\r\n");
>
>   ->  if (!feof(fl)) {
>       if (strlen(buf) + strlen(tmp) + 1 > MAX_STRING_LENGTH) {
>         log("SYSERR: %s: string too big (%d max)", name,
>   MAX_STRING_LENGTH);
>  *buf = '\0';
>  return (-1);
>       }
>       strcat(buf, tmp);
>     }
>
>

<snip>

Just looking at things here and I have a few questions.  First, that line
where the trailing return is removed, shouldn't read:

    *(tmp[strlen(tmp)-1])= '\0';

Here is what I'm suspecting. fgets() returns NULL if either the end
of file is reached or a read error occured. A lot of file Circle reads are
terminated with a lone $ character, and NOT followed by  a return. So,
after the call to fgets() for that last line, we have

    tmp  = "$\0"        for tmp at some address X

that second line removes return char, which in this case, is not there:

    strlen(tmp) = 1    so that line makes tmp[0] = '\0' which in fact
makes X, the address of tmp, equal to NULL.

next time through the loop, we are at EOF, fgets() returns NULL, and
tmp is untouched, so still = '\0' = NULL

and then the actual access violation is on the strcat() call, which makes
some sense as usually the debugger will show one past the error on an
access violation (in my limited experience).

I would suggest at least replacing the third line (in the above snipped code)
to change the contents and not the address. But furthermore,  checking for
fgets()'s return value in line two would make sense.  Maybe something like:

/* Defined somewhere at the beginning of the block */
char  *returnptr;

 if (fgets(tmp, READ_SIZE, fl))
   do
  {
       /* Remove the trailing \n, if present */
       if ((returnptr = strchr(tmp, '\10')))
         *returnptr = '\0';

      strcat(tmp, "\r\n");

      if ((strlen(buf) + strlen(tmp) + 1) >  MAX_STRING_LENGTH)
      {
         log("SYSERR: %s: string too big (%d max)", name, MAX_STRING_LENGTH);
         *buf = '\0';
         return (-1);
       }

       strcat(buf, tmp);

   }  while (fgets(tmp, READ_SIZE, fl));

Hope this is right and that it is of some help (me just a budding coder) :)
caveat emptor

Claude Belisle


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



This archive was generated by hypermail 2b30 : 04/10/01 PDT