Thread: String is getting mysteriously knackered

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

    Unhappy String is getting mysteriously knackered

    Hi, I am trying to write a program to open zzt files, but I have come across a problem which I don't understand.

    If I printf the world.title string before I have called load_board it works fine, but if I try and printf it after load_board has been called it crashes. This makes me think that the load_board function is crapping over the world.title string, but I can't see where its touching it at all!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    /*    unsigned short int c;   / Two byte thingy */
    /*    unsigned char d;        / One byte thingy */
    
    
    /* Map structure */
    struct Sworld
    {
        int board_count;
        int start_board;
        
        int start_ammo;
        int start_gems;
        int start_health;
        int start_torches;
        
        int torch_cycles_left;
        int energiser_cycles_left;
        
        bool blue_key;
        bool green_key;
        bool cyan_key;
        bool red_key;
        bool purple_key;
        bool yellow_key;
        bool white_key;
        
        int start_score;
        
        char *title;
        int time_left;
        
        bool saved_game;
    }; 
    
    /* Tile structure */
    struct Stile
    {
        char code;
        char colour;
    };
        
    /* Board Structure */
    struct Sboard
    {
        char *title;
        char *message;
        struct Stile tile[1500];
        
        int object_count;
        int maximum_shots_fired;
        int time_limit;
        
        
        int board_north;
        int board_south;
        int board_west;
        int board_east;
        
        bool dark;
        bool teleport_when_hurt;    
    };    
    
    /* Functions */
    bool load_world(char *file_name);
    void load_board(FILE *file_pointer);
    
    /* Variables */
    struct Sworld world;
    struct Sboard board;
    
    int main(int argc, char *argv[])
    {
      
        if (load_world("BOB.ZZT") == false)
            printf("Cock up loading map\n");
           
       /* if (load_world("SAVED.SAV") == false)
            printf("Cock up loading map\n"); */
      
        printf("map title: %s\n", world.title);  
    
        if (world.saved_game == true)
            printf("Its a saved game\n");
        else
            printf("Its not a saved game\n");
    
        system("PAUSE");	
        
        free(world.title);
        return 0;
    }
    
    bool load_world(char *file_name)
    {
        FILE *file_pointer;
        char buffer[512];       /* Header goes here */
        int i, title_length;
        
        file_pointer = fopen(file_name, "r");
        if (file_pointer == NULL)
        {
            printf("FAILED opening world file: %s\n", file_name);
            system("PAUSE");
            return false;
        }
        else
            printf("Opened world file: %s\n", file_name);    
        
        for (i = 0; i < 512; i++)
            buffer[i] = getc(file_pointer);
        
        world.board_count = (unsigned short)buffer[2] + buffer[3] * 256;
        world.start_ammo = (unsigned short)buffer[4] + buffer[5] * 256;
        world.start_gems = (unsigned short)buffer[6] + buffer[7] * 256;
        world.blue_key = buffer[8];
        world.green_key = buffer[9];
        world.cyan_key = buffer[10];
        world.red_key = buffer[11];
        world.purple_key = buffer[12];
        world.yellow_key = buffer[13];
        world.white_key = buffer[14];
        world.start_health = (unsigned short)buffer[15] + buffer[16] * 256;
        world.start_board = (unsigned short)buffer[17] + buffer[18] * 256;
        world.start_torches = (unsigned short)buffer[19] + buffer[20] * 256;
        world.torch_cycles_left = (unsigned short)buffer[21] + buffer[22] * 256;
        world.energiser_cycles_left = (unsigned short)buffer[23] + buffer[24] * 256;
        world.start_score = (unsigned short)buffer[27] + buffer[28] * 256;
        
        title_length = buffer[29];
        world.title = malloc(title_length + 1);
        for (i = 0; i < title_length; i++)
            world.title[i] = buffer[30 + i];
        world.title[i] = '\0'; 
        
        world.saved_game = buffer[264];
        
        printf("Board Count: %d\n",world.board_count);
        
        printf("Loaded world: %s\n", world.title);
        
        load_board(file_pointer);
    
        fclose(file_pointer);
    
        return true;
    }    
    
    void load_board(FILE *file_pointer)
    {
        char *buffer;
        int i, board_size, title_length;
        int current_tile = 0;
        
        /* Read the board into the buffer */
        buffer = malloc(53);
        
        for (i = 0; i < 53; i++)
            buffer[i] = getc(file_pointer);
        
        /* Get the board size */    
        board_size = (unsigned short)buffer[0] + buffer[1] * 256; 
            
        /* Get the title */
        title_length = buffer[2];
        board.title = malloc(title_length + 1);
        for (i = 0; i < title_length; i++)
            board.title[i] = buffer[3 + i];
        board.title[i] = '\0';
        
        free(buffer);
        
        printf("Board title: %s\n", board.title);
        
        buffer = malloc(3);
        
        /* Get all the tiles put into the board.tile array */
        while (current_tile < 1500)
        {    
            for (i = 0; i < 3; i++)
                buffer[i] = getc(file_pointer);
            
            printf("Repeat amount: %d\n",buffer[0]);
            printf("Code: %d\n",buffer[1]);
            printf("Colour: %d\n",buffer[2]);
            
            
            
            for (i = 0; i < buffer[0]; i++)
            {
                board.tile[current_tile + i].code = buffer[1];
                board.tile[current_tile + i].colour = buffer[2];
                
                current_tile++;
            }   
            printf("Current_tile: %d\n",current_tile);
            system("PAUSE");
            
        }     
    
        free(board.title);
        free(buffer);
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    title_length = buffer[29];
    world.title = malloc(title_length + 1);

    title_length = buffer[2];
    board.title = malloc(title_length + 1);

    One of these is wrong for sure, since the second causes a memory leak if nothing else.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2004
    Posts
    114
    Quote Originally Posted by Salem
    title_length = buffer[29];
    world.title = malloc(title_length + 1);

    title_length = buffer[2];
    board.title = malloc(title_length + 1);

    One of these is wrong for sure, since the second causes a memory leak if nothing else.
    I don't understand how its causing a memory leak. I am freeing board.title.

    edit: Just checked and the title_length is definately being set to the length of the string (not including terminating null).
    Last edited by kzar; 04-10-2005 at 08:06 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 04-25-2008, 02:45 PM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM
  4. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM