[vox-tech] [C newbie]C program is acting weird...

Jeff Newmiller vox-tech@lists.lugod.org
Thu, 31 Jan 2002 23:25:47 -0800 (PST)


On Thu, 31 Jan 2002, Ryan wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> for some reason this is spitting out 3 char responses once in a while, anyone 
> have any ideas? I don't know much C, this is just some code I modified.
> 
> Also, if anyone knows how to get it to include numbers mixed in with the 
> letters i'd like to know how.

Change the loop statement to a block of code that assigns a number from,
say, 0 to 35, to string[i].  Then use an if statement or ?: operator to
add either 'a' or ('0'-26) to that number depending whether it is less
than 26 or not.

> - ------
> 
> #include <stdio.h>
> #include <sys/types.h>
> #include <unistd.h>
> #include <signal.h>
> #include <stdlib.h>
> #include <time.h>
> #include <string.h>
> 
> #include "version.h"
> 
> #define SESSION_TIMEOUT 20
> 
> #define MAX_RESPONSE 200
> #define MAX_REQUEST 100
> 
> #define MIN_LEN 4
> #define MAX_LEN 9
> 
> char *randusername()
> {
>         char *string;

You have not initialized space to put the characters that this string
points to, so you are putting them in, ah, unpredictable locations in
memory.  The behavior of the program after you write to string[0] is
undefined. I would recommend "static char string[ MAX_LEN+1 ]".

>         int i, length;
>         // randomly choose a length betweem MIN_LEN and MAX_LEN
>         length = MIN_LEN + random() / (RAND_MAX / (MAX_LEN + 2 - MIN_LEN))-1;

random() may return zero.  length = 4 + stuff_that_could_be_zero - 1,
which can be looked at as length = 3 + stuff_that_could_be_zero.

>         if (string = malloc(length + 2), string == NULL)
>                 return NULL;
>         for (i = 0; i < length; i++)
>                 // does your head hurt yet?
>                 string[i] = 'a' + random() / (RAND_MAX / ('z' + 1 - 'a'));

So, if length == 3, after this loop i == 3 and string[0] through
string[2] are initialized ...

>         // zero terminate!
>         i++;

... now i is 4 ...

>         string[i] = '\0';

and if string[0] through string[2] are 'a', 'b', and 'c', then who knows
what string[3] is because it never got initialized, but now 
string[4] == '\0' and we have a four character string with a garbage
character just before the null character.  Just to make things
interesting, this garbage character could be a null character!

>         return string;
> }

I highly recommend learning how to use gdb or ddd to trace through things
like this.

---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<jdnewmil@dcn.davis.ca.us>        Basics: ##.#.       ##.#.  Live Go...
                                      Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...2k
---------------------------------------------------------------------------