Thread: linked list problem

  1. #1
    Registered User
    Join Date
    May 2004
    Posts
    114

    Question linked list problem

    Hi everyone, I have a mysterious problem with my program. I have narrowed it down to this code by using the debuger:

    Code:
                /* Loop through the snakes, moving them */
                current_snake = first_snake;
                while ( current_snake != NULL )
                {
                    move_snake(current_snake);
                    current_snake = current_snake->next_snake;
                }
    The problem with it seems to be that the second time through (there are / should be two items in the linked list) the pointer is garbage, but not NULL so it tries to call the move_snake function and therefore segfaults.

    Now I have the feeling that the bit of code there isn't the problem because it only crashes when the game tries to restart after a snake has crashed and not the first time its run, so I guess theres a problem with the function to remove all the snakes or with the function to add them again, although I have looked at them a lot and can't see a problem. Anyway here they are:

    Code:
    void add_snake(Econtrol control,int x, int y)
    {
        struct snake *new_snake;
        
        /* Allocate the memory and set the data */
        new_snake = malloc(sizeof(struct snake));
        new_snake->state = RIGHT;
        new_snake->control = control;
        
        /* Add two parts to the snake */
        new_snake->first_part = NULL;
        add_part(new_snake, x, y);
        add_part(new_snake, x + 1, y);
        
        /* Put the snake at the frount of the list */
        new_snake->next_snake = first_snake; 
        first_snake = new_snake;
    }
    
    void remove_snakes()
    {
        struct part *current_part, *next_part;
        struct snake *current_snake, *next_snake;
        current_snake = first_snake;
        first_snake = NULL; 
        
        while ( current_snake != NULL )
        {
            current_part = current_snake->first_part;
            current_snake->first_part = NULL;
    
            while ( current_part != NULL )
            {
                next_part = current_part->next_part;
                free(current_part);
                current_part = next_part;
            }
            
            next_snake = current_snake->next_snake;
            free(current_snake);
            current_snake = next_snake;
        }      
    }
    Hopefully its just a stupid mistake but I am totaly stuck trying to fix it! Thanks

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    You need to make sure the next_snake pointer in the last item in the list points to NULL. Make sure that when your program first starts, first_snake points to NULL. If that doesn't fix your problem, then you will need to post the code to the move_snake() function.

  3. #3
    Registered User
    Join Date
    May 2004
    Posts
    114
    Hmm, I am pretty sure I'm setting the next_snake pointer to NULL on the last snake because the first_snake pointer should be NULL when the first snake is created if you see what I meen.

    The move_snake function crashes right at the start, on this line:
    "x = current_snake->first_part->x_pos;", so I don't think the rest of the function is really important. I don't really know what is important though so here is all of the code:

    Code:
    #include <SDL/SDL.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    /* Defines */
    #define MAPWIDTH 20
    #define MAPHEIGHT 20
    #define DELAY 100
    
    typedef enum {PLAYER1, PLAYER2, COMPUTER} Econtrol;
    
    /* Item structure */
    struct item
    {
        int x_pos;
        int y_pos;
    };    
    
    /* Structure for snake parts */
    struct part
    {
        int x_pos, y_pos;
        struct part *next_part;  /* Pointer to next part */
        struct part *prev_part;  /* Pointer to prev part */
    };
    
    /* Snake structure */
    struct snake
    {
        struct part *first_part; /* Pointer to the first part of the snake */
        enum Estate {RIGHT, LEFT, UP, DOWN} state; /* State of the snake */
        Econtrol control; /* Thing controlling snake */
        struct snake *next_snake;  /* Pointer to next snake */
    };
    
    /* Variables */
    struct snake *first_snake; /* Player 1's snake */
    struct item apple; /* The apple item's variable */
    int map[MAPWIDTH][MAPHEIGHT]; /* Map array for storing tile type */
    float last_time; /* Float number to store the last time the snake moved */
    bool game_running = false; /* This controls the game loop */
    bool paused = false; /* Used for pausing the game */
    SDL_Surface *screen, *sprite_image, *item_image, *tile_image; /* Some SDL surfaces */
    
    /* Function Declarations */
    int main(int argc, char *argv[]); 
    bool game_init(); /* Sets the game up to start with */
    void new_game(); /* Starts a new game */
    void remove_snakes(); /* Remove old snakes */
    void load_map(char *mapname);
    void add_snake(Econtrol control,int x, int y);
    void game_loop(); /* The main game loop */
    void get_input(); /* Gets and deals with keyboard input */
    void do_ai();
    void add_apple(); /* Puts the apple in a random position */
    void move_snake (struct snake *current_snake); /* Moves the snake on */
    void add_part(struct snake *current_snake, int x, int y); /* Adds a new part of the snake to the frount */
    void remove_part(struct snake *current_snake); /* Removes the last part of the snake */
    void edge_collision(int *x, int *y); /* Checks if the part has gone over the edge */
    bool apple_collision(int x, int y); /* Checks to see if the part has eaten the apple */
    bool snake_collision(int x, int y);
    void draw_apple(); /* Draw the apple */
    void draw_snake(); /* Draw the snake */
    void draw_part(int src_x, int src_y, int dest_x, int dest_y); /* Draw the part of the snake */
    void draw_map(); /* Draw the map */
    void draw_tile(int src_x, int src_y, int pos_x, int pos_y); /* Draw the tile of the map */
    void game_close(); /* Close the game and tidy up */
    
    int main(int argc, char *argv[])
    {
        atexit(game_close);
        
        if (game_init() == false)
            exit(1);
        
        while (game_running == true)
            game_loop();
    }    
    
    bool game_init()
    {
        int x, y;
        SDL_Surface *temp;
        
        /* Initialize SDL */
        if (SDL_Init(SDL_INIT_VIDEO) != 0)
        {
            printf("Unable to initialize SDL\n");
            return false;
        }
        
        /* Set the window size up */
        screen = SDL_SetVideoMode(MAPWIDTH * 10, MAPHEIGHT * 10, 16, SDL_DOUBLEBUF);
        if (screen == NULL)
        {
            printf("Unable to set video mode\n");
            return false;
        }
        
        /* Set the windows caption */
        SDL_WM_SetCaption("Snake Attempt", NULL);   
        
        /* Get rid of the cursor */
        SDL_ShowCursor( SDL_DISABLE );
        
        /* Load the sprite image up */
        temp = SDL_LoadBMP("sprites.bmp");
        if (temp == NULL)
        {
            printf("Unable to load picture\n");
            return false;
        }
        SDL_SetColorKey(temp, SDL_SRCCOLORKEY | SDL_RLEACCEL, (Uint32) SDL_MapRGB(temp->format, 255, 255, 255));     
        sprite_image = SDL_DisplayFormat(temp);
        
        /* Load the item image up */
        temp = SDL_LoadBMP("items.bmp");
        if (temp == NULL)
        {
            printf("Unable to load picture\n");
            return false;
        }
        SDL_SetColorKey(temp, SDL_SRCCOLORKEY | SDL_RLEACCEL, (Uint32) SDL_MapRGB(temp->format, 255, 255, 255));     
        item_image = SDL_DisplayFormat(temp);
        
        /* Load the tiles image up */
        temp = SDL_LoadBMP("tiles.bmp");
        if (temp == NULL)
        {
            printf("Unable to load picture\n");
            return false;
        }
        SDL_SetColorKey(temp, SDL_SRCCOLORKEY | SDL_RLEACCEL, (Uint32) SDL_MapRGB(temp->format, 255, 255, 255));     
        tile_image = SDL_DisplayFormat(temp);
        
        /* Free the tempory serface we used to load the images */
        SDL_FreeSurface(temp);
        
        /* Start the game */
        new_game();
        game_running = true;
        
        return true;
    }   
    
    void new_game()
    {
        /* Pause the game */
        paused = true;
    
        /* Remove all of the snakes */
        remove_snakes();
    
        /* Add new snakes */      
        add_snake( PLAYER1, ((MAPWIDTH / 3) * 2) , (MAPHEIGHT / 2) - 1 );
        add_snake( COMPUTER, (MAPWIDTH / 3), (MAPHEIGHT / 2) - 1 );
    
        /* Load the map */
        load_map("map.txt");
        
        /* Sort the time out */
        last_time = SDL_GetTicks();
        
        /* Add an apple */
        add_apple();
        printf("test");
    }   
    
    void remove_snakes()
    {
        struct part *current_part, *next_part;
        struct snake *current_snake, *next_snake;
        current_snake = first_snake;
        first_snake = NULL; 
        
        while ( current_snake != NULL )
        {
            current_part = current_snake->first_part;
            current_snake->first_part = NULL;
    
            while ( current_part != NULL )
            {
                next_part = current_part->next_part;
                free(current_part);
                current_part = next_part;
            }
            
            next_snake = current_snake->next_snake;
            free(current_snake);
            current_snake = next_snake;
        }      
    }    
    
    void load_map(char *mapname)
    {
        FILE *map_file;
        char c;
        bool in_tag, in_var;
        char *var, *tag;
        int x, y;
           
        map_file = fopen(mapname, "r");
        if (map_file == NULL)
        {
            printf("Error opening map: %s\n", mapname); 
        }
        else
        {
            x = 0;
            y = 0;
            while(1)
            {
                c = fgetc(map_file);
                
                if (c == EOF)
                    break;
                    
                switch (c)
                {
                    case ' ':
                        continue;
                        break;
                    case '\n':
                        x = -1;
                        y ++;
                        break;
                    case '0':
                        map[x][y] = 0;
                        break;
                    case '1':
                        map[x][y] = 1;
                        break;
                    default:
                        break;
                }    
        
                x ++;
            }    
            fclose(map_file);
        }    
    }    
    
    void add_snake(Econtrol control,int x, int y)
    {
        struct snake *new_snake;
        
        /* Allocate the memory and set the data */
        new_snake = malloc(sizeof(struct snake));
        new_snake->state = RIGHT;
        new_snake->control = control;
        
        /* Add two parts to the snake */
        new_snake->first_part = NULL;
        add_part(new_snake, x, y);
        add_part(new_snake, x + 1, y);
        
        /* Put the snake at the frount of the list */
        new_snake->next_snake = first_snake; 
        first_snake = new_snake;
    }
        
    void game_loop()
    {
        struct snake *current_snake;
        float time_passed, current_time;
        
        /* Get the time and figure out time passed since last movement */
        current_time = SDL_GetTicks();
        time_passed = current_time - last_time;
        
        /* Get the input from the players and the computer AI */
        get_input();
        do_ai();
        
        /* If the game isn't paused */
        if (!paused)
        {
            /* And the time passed since movement is bigger than the delay */
            if ( time_passed >= DELAY )
            {
                /* Add the delay amount to the last time, this is better than
                   setting last time to current time incase more time than the 
                   delay has passed */
                last_time += DELAY;
                
                /* Loop through the snakes, moving them */
                current_snake = first_snake;
                while ( current_snake != NULL )
                {
                    move_snake(current_snake);
                    current_snake = current_snake->next_snake;
                }
                
            }     
        }    
         
     
        /* Draw everything to the screen */
        draw_map();
        
        /* Loop through, drawing the snakes */
        current_snake = first_snake;
        while ( current_snake != NULL )
        {
            draw_snake(current_snake);
            current_snake = current_snake->next_snake;
        }
            
        draw_apple();
        
        /* Refresh the screen */
        SDL_Flip( screen );
    }   
    
    void get_input()
    {
        SDL_Event event;
        SDL_keysym keysym;
        struct snake *current_snake;
        
        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_QUIT:
                    game_running = false;
                    break;
                    
                case SDL_KEYDOWN:
                    keysym = event.key.keysym;
                    switch(keysym.sym) 
                    {
                        case SDLK_ESCAPE:
                            game_running = false;
                            break;
                            
                        case SDLK_SPACE:
                            if (paused == true)
                                paused = false;
                            else
                                paused = true;
                            break;
    
                        case SDLK_a:
                            if (!paused)
                            {
                                current_snake = first_snake;
                                while ( current_snake != NULL )
                                {
                                    if (current_snake->control == PLAYER2)
                                        current_snake->state = LEFT;
                                        
                                    current_snake = current_snake->next_snake;
                                }
                            }    
                            break;
                            
                        case SDLK_d:
                            if (!paused)
                            {
                                current_snake = first_snake;
                                while ( current_snake != NULL )
                                {
                                    if (current_snake->control == PLAYER2)
                                        current_snake->state = RIGHT;
                                        
                                    current_snake = current_snake->next_snake;
                                }
                            }    
                            break;
    
                        case SDLK_s:
                            if (!paused)
                            {
                                current_snake = first_snake;
                                while ( current_snake != NULL )
                                {
                                    if (current_snake->control == PLAYER2)
                                        current_snake->state = DOWN;
                                        
                                    current_snake = current_snake->next_snake;
                                }
                            }    
                            break;
    
                        case SDLK_w:
                            if (!paused)
                            {
                                current_snake = first_snake;
                                while ( current_snake != NULL )
                                {
                                    if (current_snake->control == PLAYER2)
                                        current_snake->state = UP;
                                        
                                    current_snake = current_snake->next_snake;
                                }
                            }    
                            break;
                            
                        case SDLK_LEFT:
                            if (!paused)
                            {
                                current_snake = first_snake;
                                while ( current_snake != NULL )
                                {
                                    if (current_snake->control == PLAYER1)
                                        current_snake->state = LEFT;
                                        
                                    current_snake = current_snake->next_snake;
                                }
                            }    
                            break;
                        
                        case SDLK_RIGHT:
                            if (!paused)
                            {
                                current_snake = first_snake;
                                while ( current_snake != NULL )
                                {
                                    if (current_snake->control == PLAYER1)
                                        current_snake->state = RIGHT;
                                        
                                    current_snake = current_snake->next_snake;
                                }
                            }  
                            break;
                        
                        case SDLK_UP:
                            if (!paused)
                            {
                                current_snake = first_snake;
                                while ( current_snake != NULL )
                                {
                                    if (current_snake->control == PLAYER1)
                                        current_snake->state = UP;
                                        
                                    current_snake = current_snake->next_snake;
                                }
                            }  
                            break;
                            
                        case SDLK_DOWN:
                            if (!paused)
                            {
                                current_snake = first_snake;
                                while ( current_snake != NULL )
                                {
                                    if (current_snake->control == PLAYER1)
                                        current_snake->state = DOWN;
                                        
                                    current_snake = current_snake->next_snake;
                                }
                            }  
                            break;
                        
                    }
                    break;
            }
            break;
        }
    }  
    
    void do_ai()
    {
        struct snake *current_snake = first_snake;
        
        while ( current_snake != NULL )
        {
            if (current_snake->control == COMPUTER)
            {
                /* AI pathfinding stuff */
                
                /* Line of sight-ish method */
                int distance_x = apple.x_pos - current_snake->first_part->x_pos;
                int distance_y = apple.y_pos - current_snake->first_part->y_pos;
                
                if (abs(distance_x) > abs(distance_y))
                {
                    if (distance_x > 0)
                        current_snake->state = RIGHT;
                    else if (distance_x < 0)
                        current_snake->state = LEFT;
                }    
                else
                {
                    if (distance_y > 0)
                        current_snake->state = DOWN;
                    else if (distance_y < 0)
                        current_snake->state = UP;
                }    
                        
                /* Basic Method (naf!) 
                if (current_snake->first_part->x_pos > apple.x_pos)
                    current_snake->state = LEFT;
                else if (current_snake->first_part->x_pos < apple.x_pos)
                    current_snake->state = RIGHT;
                
                if (current_snake->first_part->y_pos > apple.y_pos)
                    current_snake->state = UP;
                else if (current_snake->first_part->y_pos < apple.y_pos)
                    current_snake->state = DOWN;*/
            }                        
                                                                      
            current_snake = current_snake->next_snake;
        }
    }    
    
    void add_apple()
    {
        int x, y;
    
        x = rand() % MAPWIDTH;
        y = rand() % MAPHEIGHT;
        
        apple.x_pos = x;
        apple.y_pos = y;
    }    
    
    void move_snake (struct snake *current_snake)
    {
        int x, y;
        
        x = current_snake->first_part->x_pos;
        printf("bob");
        y = current_snake->first_part->y_pos;
            
        switch (current_snake->state)
        {
                case RIGHT:
                    x += 1;
                    y += 0;
                    break;
                case LEFT:
                    x -= 1;
                    y += 0;
                    break;
                case UP:
                    x += 0;
                    y -= 1;
                    break;
                case DOWN:
                    x += 0;
                    y += 1;
                    break;
        }
            
        edge_collision(&x, &y);
      
        if ( snake_collision(x, y) )
            new_game();  
        else
        {   
            add_part(current_snake, x, y);
            
            if ( apple_collision(x, y) )
                add_apple();
            else
                remove_part(current_snake);
        }    
    }
        
    
    void add_part(struct snake *current_snake, int x, int y)
    {
        /* Pointer to the next item in the list */
        struct part *new_part;
        
        new_part = malloc(sizeof(struct part));
        new_part->x_pos = x;
        new_part->y_pos = y;
        new_part->prev_part = NULL;
    
        if (current_snake->first_part == NULL)
        {
            new_part->next_part = NULL;
            current_snake->first_part = new_part;
        }    
        else
        {
            new_part->next_part = current_snake->first_part;
            current_snake->first_part->prev_part = new_part;
            current_snake->first_part = new_part;
        }    
    }    
    
    void remove_part(struct snake *current_snake)
    {
        struct part *current_part, *next_part;
        
        current_part = current_snake->first_part;
        
        while ( current_part != NULL )
        {
            next_part = current_part->next_part;
            
            if ( next_part == NULL )
            {
                current_part->prev_part->next_part = NULL;
                
                free(current_part);
            }   
                current_part = next_part;
        
        }
    } 
    
    void edge_collision(int *x, int *y)
    {
        if (*x > MAPWIDTH - 1)
            *x = 0;
        if (*x < 0)
            *x = MAPWIDTH - 1;
        
        if (*y > MAPHEIGHT - 1)
            *y = 0;
        if (*y < 0)
            *y = MAPHEIGHT - 1;
    }    
    
    bool snake_collision(int x, int y)
    {
        struct part *current_part;
        struct snake *current_snake;
        
        current_snake = first_snake;
        
        
        
        while ( current_snake != NULL )
        {
            current_part = current_snake->first_part;
            
            while ( current_part != NULL )
            {
                if ( x == current_part->x_pos && y == current_part->y_pos )
                    return true;
            
                current_part = current_part->next_part;
            }
            
            current_snake = current_snake->next_snake;
        }       
        return false;
    }    
    
    bool apple_collision(int x, int y)
    {
        if ( (x == apple.x_pos && y == apple.y_pos) )
            return true;
        else
            return false;
    }    
    
    void draw_apple()
    {
        SDL_Rect src, dest;
        
        src.x = 0;
        src.y = 0;
        src.w = 10;        
        src.h = 10;
        dest.x = apple.x_pos * 10;
        dest.y = apple.y_pos * 10;
        dest.w = 10;        
        dest.h = 10;
    
        SDL_BlitSurface( item_image, &src, screen, &dest );
    }
        
    void draw_snake(struct snake *current_snake)
    {
        struct part *current_part;
        
        current_part = current_snake->first_part;
        
        while ( current_part != NULL )
        {
            /* Its a head */
            if (current_part->prev_part == NULL)
            {
                /* Left direction head */
                if (current_part->x_pos > current_part->next_part->x_pos)
                    draw_part(0, 3, current_part->x_pos, current_part->y_pos);
                
                /* Right direction head */
                if (current_part->x_pos < current_part->next_part->x_pos)
                    draw_part(2, 3, current_part->x_pos, current_part->y_pos);      
                    
                /* Up direction head */
                if (current_part->y_pos > current_part->next_part->y_pos)
                    draw_part(3, 3, current_part->x_pos, current_part->y_pos);
                
                /* Down direction head */
                if (current_part->y_pos < current_part->next_part->y_pos)
                    draw_part(1, 3, current_part->x_pos, current_part->y_pos);             
            }    
            
            /* Its a tail */
            if ( (current_part->next_part == NULL) && (current_part->prev_part != NULL) )
            {
                /* Left direction tail */
                if (current_part->x_pos > current_part->prev_part->x_pos)
                    draw_part(0, 4, current_part->x_pos, current_part->y_pos);
                
                /* Right direction tail */
                if (current_part->x_pos < current_part->prev_part->x_pos)
                    draw_part(2, 4, current_part->x_pos, current_part->y_pos);      
                    
                /* Up direction tail */
                if (current_part->y_pos > current_part->prev_part->y_pos)
                    draw_part(1, 4, current_part->x_pos, current_part->y_pos);
                
                /* Down direction tail */
                if (current_part->y_pos < current_part->prev_part->y_pos)
                    draw_part(3, 4, current_part->x_pos, current_part->y_pos);         
            }    
                
    
            
            /* Its a body part */    
            if ( (current_part->prev_part != NULL) && (current_part->next_part != NULL) )
            {
                /* Left direction body */
                if ( (current_part->x_pos > current_part->next_part->x_pos) && (current_part->x_pos < current_part->prev_part->x_pos) )
                    draw_part(2, 0, current_part->x_pos, current_part->y_pos);
                
                /* Right direction body */
                if ( (current_part->x_pos < current_part->next_part->x_pos) && (current_part->x_pos > current_part->prev_part->x_pos) )
                    draw_part(0, 0, current_part->x_pos, current_part->y_pos);
                
                /* Up direction body */                
                if ( (current_part->y_pos > current_part->next_part->y_pos) && (current_part->y_pos < current_part->prev_part->y_pos) )
                    draw_part(1, 0, current_part->x_pos, current_part->y_pos); 
                    
                /* Down direction body */                
                if ( (current_part->y_pos < current_part->next_part->y_pos) && (current_part->y_pos > current_part->prev_part->y_pos) )
                    draw_part(3, 0, current_part->x_pos, current_part->y_pos);            
                
                /* CORNERS */
                
                /* Up to left corner */
                if ( (current_part->prev_part->x_pos < current_part->x_pos ) && (current_part->next_part->y_pos > current_part->y_pos) )
                    draw_part(2, 2, current_part->x_pos, current_part->y_pos);
    
                /* Up to Right corner -- */                
                if ( (current_part->prev_part->x_pos > current_part->x_pos ) && (current_part->next_part->y_pos > current_part->y_pos) )
                    draw_part(0, 1, current_part->x_pos, current_part->y_pos);
                    
                /* Down to Left corner */
                if ( (current_part->prev_part->x_pos < current_part->x_pos ) && (current_part->next_part->y_pos < current_part->y_pos) )
                    draw_part(2, 1, current_part->x_pos, current_part->y_pos);
                
                /* Down to Right corner */ 
                if ( (current_part->prev_part->x_pos > current_part->x_pos ) && (current_part->next_part->y_pos < current_part->y_pos) )
                    draw_part(0, 2, current_part->x_pos, current_part->y_pos);
    
                /* Left to Up corner */               
                if ( (current_part->prev_part->y_pos < current_part->y_pos ) && (current_part->next_part->x_pos > current_part->x_pos) )
                    draw_part(1, 1, current_part->x_pos, current_part->y_pos); 
                
                /* Left to Down corner */               
                if ( (current_part->prev_part->y_pos > current_part->y_pos ) && (current_part->next_part->x_pos > current_part->x_pos) )
                    draw_part(3, 2, current_part->x_pos, current_part->y_pos); 
                    
                /* Right to up corner */
                if ( (current_part->prev_part->y_pos < current_part->y_pos ) && (current_part->next_part->x_pos < current_part->x_pos) )
                    draw_part(1, 2, current_part->x_pos, current_part->y_pos); 
                    
                /* Right to Down corner */               
                if ( (current_part->prev_part->y_pos > current_part->y_pos ) && (current_part->next_part->x_pos < current_part->x_pos) )
                    draw_part(3, 1, current_part->x_pos, current_part->y_pos);    
            }
                
            current_part = current_part->next_part;
        }   
    }    
    
    void draw_part(int src_x, int src_y, int dest_x, int dest_y)
    {
        SDL_Rect src, dest;
        
        src.x = src_x * 10;
        src.y = src_y * 10;
        src.w = 10;        
        src.h = 10;
        dest.x = dest_x * 10;
        dest.y = dest_y * 10;
        dest.w = 10;        
        dest.h = 10;
    
        SDL_BlitSurface( sprite_image, &src, screen, &dest );
    }    
    
    void draw_map()
    {
        int x, y;
        int src_x, src_y;
        SDL_Rect src, dest;
        
        
        for (x = 0; x < MAPWIDTH; x++)
            for (y = 0; y < MAPHEIGHT; y++)
            {
                switch (map[x][y] )
                {
                    case 0:
                        src_x = 10;
                        src_y = 0;
                        break;
                    case 1:
                        src_x = 0;
                        src_y = 0;
                        break;
                }
                
                draw_tile(src_x, src_y, x, y);    
    
            }    
    
        
    }    
    
    void draw_tile(int src_x, int src_y, int pos_x, int pos_y)
    {
        SDL_Rect src, dest;
        
        src.x = src_x;
        src.y = src_y;
        src.w = 10;
        src.h = 10;
        dest.x = pos_x * 10;
        dest.y = pos_y * 10;
        dest.w = 10;
        dest.h = 10;
        
        SDL_BlitSurface( tile_image, &src, screen, &dest );
    }    
    
    void game_close()
    {
        remove_snakes();
        SDL_FreeSurface(sprite_image);
        SDL_Quit();
    }
    You should know that each snake has a linked list to store the individual sections of it, I'm starting to think there might be a problem with how I am creating / freeing those linked lists.

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    because the first_snake pointer should be NULL when the first snake is created
    Show me where the first_snake pointer is being set to NULL.

  5. #5
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by bithub
    Show me where the first_snake pointer is being set to NULL.
    Looks like right here:
    Code:
    /* Variables */
    struct snake *first_snake; /* Player 1's snake */
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  6. #6
    Registered User
    Join Date
    May 2004
    Posts
    114
    I think your right becuase changing it to "struct snake *first_snake = NULL;" made no difference at all.

    edit: Interestingly though, if I delete one of the add_snake calls so there is only one snake in the game, It doesn't crash.

    edit2: Also I have tried putting this line after the add_snake calls to make sure that the last next snake pointer was NULL and it had no effect

    Code:
    /* Add new snakes */      
        add_snake( PLAYER1, ((MAPWIDTH / 3) * 2) , (MAPHEIGHT / 2) - 1 );
        add_snake( COMPUTER, (MAPWIDTH / 3), (MAPHEIGHT / 2) - 1 );
    
        first_snake->next_snake->next_snake = NULL;
    Last edited by kzar; 02-05-2005 at 08:01 AM.

  7. #7
    Registered User
    Join Date
    May 2004
    Posts
    114
    Right I have been trying to debug it some more. I have been looking at the values of the snake pointers in that loop which should call move_snake for each snake but is causing problems. As it segfaults here are some interesting values:

    current_snake = (struct snake *) 0xfeeefeee
    current_snake->next_snake = (struct snake *) 0x0
    current_snake->first_part = (struct part *) 0x0

    first_snake = (struct snake *) 0xb6cd38
    first_snake->next_snake = (struct snake *) 0xb6ccc0
    first_snake->next_snake->next_snake = (struct snake *) 0x0
    So from looking at the first_snake using the next_snake pointers I don't see why on earth the current_snake ever gets to 0xfeeefeee ! I can ovbiously see why it crashes though, the first_part of it is null so when it tries to get to the x_pos it can't. Argh!

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    How about you rewrite this and get rid of all of the global variables so it's actually easy to follow what's going on?

    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    May 2004
    Posts
    114
    Quote Originally Posted by quzah
    How about you rewrite this and get rid of all of the global variables so it's actually easy to follow what's going on?

    Quzah.

    Is a global variable one that is declared outside of a function ? If so how would I code it withought them? Surely I need a pointer to the first_snake in the linked list and a place to store the last_time thats outside of the game loop etc?

    (Is anything else coded in a backwards way? I'm trying to code it properly.)

    Thanks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help sorting a linked list. Beginner
    By scarlet00014 in forum C Programming
    Replies: 1
    Last Post: 09-27-2008, 06:16 PM
  2. singly linked circular list
    By DarkDot in forum C++ Programming
    Replies: 0
    Last Post: 04-24-2007, 08:55 PM
  3. Replies: 6
    Last Post: 03-02-2005, 02:45 AM
  4. Linked list with two class types within template.
    By SilasP in forum C++ Programming
    Replies: 3
    Last Post: 02-09-2002, 06:13 AM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM