0

I'm super new to C programming, only taking it for a required course in uni and finally getting done with my final project this week.

Problem is every time I run this code I get an error message that says "segmentation fault: 11" and I'm not sure what that means.

The code is supposed to run two-player race. Each player has a pre-determined "speed modifier", aka a number from 0-9. A random number from 1-10 is generated; if the speed modifier + the random number doesn't exceed 10, then the speed modifier is added and the car moves that total amount of "spaces". The whole race track is 90 "spaces".

Every time I run this code it works somewhat fine (more on that later) for one or two iterations, then gives out that error message. I normally don't ask for homework help online but I'm honestly so confused. Any help at all would be super appreciated.

Here is the relevant code:

Race (main) function:

int race(struct car cars[4], int mode)
{
/* Define variables. */
int endgame, i, x, y, first=-1, second=-1, randnum, spaces[]={};
char input[100];
/* Declare pointer. */
int *spacesptr=spaces;

for (i=0; i<mode; i++)
{
    /* Array spaces will keep track of how many spaces a car has moved. Start each car at 0. */
    spaces[i]=0;
}

/* Clear screen before race. */
system("cls");

/* Print message to indicate race has started. */
printf("\n3...\n2...\n1...\nGO!\n\n");

/* Open do while loop to keep race running until it is over. */
do
{
    /* Conditions for two player mode. */
    if (mode==2)
    {
        /* Run the next block of code once for each player. */
        for (i=0; i<mode; i++)
        {
            /* Generate random integer from 1-10 to determine how many spaces the car moves. */
            x=10, y=1;
            randnum=(getrandom(x, y));
            spaces[i]=spaces[i]+randnum;

            /* Call function speedmod to determine if speedmodifier should be added. */
            speedmod(cars, spaces, randnum);

            /* Rank players. */
            if (spaces[i]>89)
            {
                if (first==-1)
                {
                    first=i;
                }

                else if (second==-1)
                {
                    second=i;
                }

            }

        }
    }

    ...

    /* Call function displayrace to display the race. */
    displayrace(cars, spaces, mode);

    /* Call function endgame to determine if the race is still going. */
    endgame=fendgame(mode, spaces);

    if (endgame==0)
    {
        /* Ask for player input. */
        printf("Enter any key to continue the race:\n");
        scanf("%s", input);

        /* Clear screen before loop restarts. */
        system("cls");
    }

} while (endgame==0);
}

Random number function:

int getrandom(int x, int y)
{
/* Define variable. */
int randnum;

/* Use time seed. */
srand(time(0));

/* Generate random numbers. */
randnum=(rand()+y) % (x+1);

return randnum;
}

Add speed modifier function:

void speedmod(struct car cars[4], int spaces [], int go)
{
/* Declare pointer. */
int *spacesptr=spaces;

/* If the number of spaces plus the speed modifier is less than or equal to ten... */
if (spaces[go]+cars[go].speedmod<=10)
{
    /* ...add the speed modifier to the number of spaces moved. */
    spaces[go]=spaces[go]+cars[go].speedmod;
}
}

Display race function:

void displayrace(struct car cars[4], int spaces[], int mode)
{
/* Define variables. */
int i, j;

/* Declare pointers. */
int *spacesptr=spaces;
struct car *carsptr=cars;

/* Open for loop. */
for (i=0; i<mode; i++)
{
    /* Print racecar number. */
    printf("#%d\t", cars[i].carnumber);

    /* For every space the car has moved... */
    for (j=0; j<spaces[i]; j++)
    {
        if (j<=90)
        {
            /* ...print one asterisk. */
            printf("*");
        }
    }

    /* New line. */
    printf("\n");
}
}

End game function:

int fendgame(int mode, int spaces[])
{
/* Define variables. */
int racers=0, endgame=0, i;
/* Declare pointer. */
int *spacesptr=spaces;

/* Open for loop. */
for (i=0; i<mode; i++)
{
    /* If any of the racers have not yet crossed the finish line (90 spaces)... */
    if (spaces[i]<=90)
    {
        /* ...then add to the number of racers still in the game. */
        racers++;
    }
}

/* If all the racers have crossed the finish line... */
if (racers==0)
{
    /* ...then end the game. */
    endgame=1;
}

return endgame;
}

Now to be more specific on the issue...it's messing up somewhere on the "for" loop in the race function. For some reason it doesn't actually go through each iteration of "i", specifically in this line:

spaces[i]=spaces[i]+randnum;

I know this because I put in printf statements to display the value of spaces[i] before and after; the first iteration of i works fine...but the second iteration actually uses spaces[i-1] instead and adds the randnum to that value?

And then, like I said, it crashes after one or two times of this...:-(

I know it's a lot but I'm hoping someone more experienced than I could spot the error(s) in this code for me! Please help!

Cœur
  • 37,241
  • 25
  • 195
  • 267
Christine
  • 9
  • 2
  • Er, I have, but I haven't found anything in particular that could help with this code. – Christine Apr 22 '18 at 22:43
  • 1
    You need to learn how to use a debugger. (On an unrelated issue, calling `srand()` inside `getrandom()` is a bad idea. You should only call `srand()` once at the start of your program if you want `rand()` to function properly.) – r3mainer Apr 22 '18 at 22:44
  • Thank you -- I have moved srand() to main and I'm looking up how to use a debugger now. – Christine Apr 22 '18 at 22:59
  • 1
    @Christine: Did you find [our own canonical page](https://stackoverflow.com/q/2346806/8586227) on the subject? It basically means that a pointer or array index is incorrect (_e.g._, uninitialized). – Davis Herring Apr 22 '18 at 23:01
  • Hi Davis -- I did find it, but I still could not find the error in my code. I'm extremely new to programming; frankly all I understand is that I am attempting to access some piece of memory which does not exist, but I don't know where or why that is occurring in my code. – Christine Apr 22 '18 at 23:36
  • when posting about a run time problem, as this question is doing, Post a [mcve] So we can reproduce the problem. – user3629249 Apr 23 '18 at 21:27
  • one of the posted functions contains `...` on a line by itself. Exactly how do you expect us to make use of that? – user3629249 Apr 23 '18 at 21:33
  • the function: `race()` signature states that the function returns an `int`. However, there is no `return ;` anywhere in that function. – user3629249 Apr 23 '18 at 21:36
  • the code uses a `struct car`, but there is no definition of the struct anywhere in the posted code – user3629249 Apr 23 '18 at 21:38
  • for ease of readability and understanding: 1) consistently indent the code. Indent after EVERY opening brace '{' Unindent before every closing brace '}' Suggest each indent level be 4 spaces 2) insert a reasonable space inside parens, inside brackets, after commas after semicolons, around C operators 3) follow the axiom: *only one statement per line and (at most) one variable declaration per statement.* – user3629249 Apr 23 '18 at 21:44
  • regarding: `system ( "cls" );` This is not portable. (not every OS has the command `cls` implemented. Suggest using the ANSI control sequences to handle erasing the screen and moving the cursor – user3629249 Apr 23 '18 at 21:51
  • regarding: `spaces[] = {}` this is trying to declare an array called 'spaces' and to initialize it to ??? Suggest `spaces[4] = {' '};` – user3629249 Apr 23 '18 at 21:55
  • there is no declaration of `mode`, nor any indication of what value(s) it can contain over the life of the program. However, there is some indication that the variable is a `int` – user3629249 Apr 23 '18 at 21:59
  • Welcome to Stack Overflow! Please [edit] your question to show us what kind of debugging you've done. I expect you to have run your [mcve] within Valgrind or a similar checker, and to have investigated with a debugger such as GDB, for example. Ensure you've enabled a full set of compiler warnings, too. What did the tools tell you, and what information are they missing? And read Eric Lippert's [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Toby Speight Apr 24 '18 at 11:33

4 Answers4

1

I believe the first user above was correct in saying that the error is because there is no initial size declared for the array, but the solution is incorrect. You would have to allocate its size dynamically using malloc.

Also, I'd shorten spaces[i]=spaces[i]+randnum to just spaces[i] += randnum.

Nick
  • 25
  • 10
  • Hi Nick...thank you for this. I'm sorry to ask but I am very new to C programming, I've been reading up on malloc since I saw this comment 20 min ago and I still don't fully understand how it works. To be clear, would the declaration look like: int *spaceptr=malloc(4*sizeof(int))? For four integers? And how would I link the pointer to the actual array? Again thanks and sorry for all the questions. – Christine Apr 22 '18 at 23:31
  • `int * spaces = (int *) malloc(sizeof(int) * 4)` This stores the memory block of the array to a pointer. You can use it like you would a normal array `spaces[0] = 5` for example, but passing it to a function is a bit different. You'd pass it as something like this `void function(int * spaces, ...)` – Nick Apr 22 '18 at 23:58
  • Hi, thanks again for the response...I've implemented that into my code and it still does not work. In fact I removed the pointer altogether and left it only as "spaces[4]={0,0,0,0}" and it still does not work. I am sorry to keep bothering you on this issue but do you have any other ideas? Really appreciate the help. – Christine Apr 23 '18 at 00:47
0

regarding: Problem is every time I run this code I get an error message that says "segmentation fault: 11" and I'm not sure what that means.

This means your program is trying to access memory that the application does not own.

For instance, a 'wild' pointer or uninitialized pointer or writing past the end of an array.

user3629249
  • 16,402
  • 1
  • 16
  • 17
0

Thanks for the help. After a ton of tinkering around with this code I finally found the issue.

I was passing randnum to the speedmod function as if it were an index of the array spaces. I changed the function to the following, where num is the random number generated and go is the index:

void speedmod(struct car cars[4], int spaces [], int num, int go)
{
    /* Declare pointer. */
    int *spacesptr=spaces;

/* If the number of spaces plus the speed modifier is less than or equal to ten... */
if (num+cars[go].speedmod<=10)
{
    /* ...add the speed modifier to the number of spaces moved. */
    spaces[go]+=cars[go].speedmod;
}
}

Works perfectly now. Thanks for the help again.

Christine
  • 9
  • 2
-1

you declare spaces[]={}, so it allocates a ptr that points to nothing. then you start writing all over it, which destroys probably your stack, your other variables, and whatever else is there -> undefined behavior.

you need to provide the memory to write to before you use it, for example spaces[1000]={}, ot however much you need.

Aganju
  • 6,295
  • 1
  • 12
  • 23
  • Hi, thank you for this response -- I've changed it to spaces[4]={} but it is still giving me the segmentation fault. – Christine Apr 22 '18 at 22:52