tags:

views:

98

answers:

2

I'm a fairly new programmer, but I consider my google-fu quite competent and I've spent several hours searching.

I've got a simple SDL application that reads from a binary file (2 bytes as a magic number, then 5 bytes per "tile") it then displays each tile in the buffer, the bytes decide the x,y,id,passability and such. So it's just level loading really.

It runs fine on any windows computer (tested windows server 2008, 7/64 and 7/32) but when I compile it on linux, it displays random tiles in random positions. I'd be tempted to say it's reading from the wrong portion in the RAM, but I implimented the magic number so it'd return an error if the first 2 bytes were out.

I'd love to figure this out myself but it's bugging me to hell now and I can't progress much further with it unless I can program on the move (my laptop runs linux). I'm using G++ on linux, mingw32g++ on windows.

bool loadlevel(int level_number)
{
    int length;
    std::string filename;
    filename = "Levels/level";
    filename += level_number+48;
    filename += ".lvl";
    std::ifstream level;
    level.open(filename.c_str(),std::ios::in|std::ios::binary);
    level.seekg(0,std::ios::end);
    length = level.tellg();
    level.seekg(0,std::ios::beg);
    char buffer[length];
    level.read(buffer,length);
    if (buffer[0] == 0x49 && buffer[1] == 0x14)
    {
        char tile_buffer[BYTES_PER_TILE];
        int buffer_place = 1;
        while(buffer_place < length)
        {
            for (int i = 1;i <= BYTES_PER_TILE;i++)
            {
                tile_buffer[i] = buffer[buffer_place+1];
                buffer_place++;
            }
            apply_surface(tile_buffer[1],tile_buffer[2],tiles,screen,&clip[tile_buffer[3]]);
        }
    }
    else
    {
        // File is invalid
        return false;
    }
    level.close();
    return true;
}

Thanks in advance!

+4  A: 

Your array handling is incorrect.
Array indexing in C/C++ begins from 0.

You have defined 'tile_buffer' to be an array sized 'BYTES_PER_TILE'.
If BYTES_PER_TILE was 5, your array would have elements tile_buffer[0] to tile_buffer[4].

In your inner for-loop you loop from 1 to 5 so a buffer overflow will occur.

I don't know if this is the cause of your problem but it certainly won't help matters.

JRT
Thankyou, fixing the code solved the problem! Makes me wonder why it worked properly on windows.
ashrossy
A: 

This is probably not an answer, but the 1-based array handling and the unneeded copying make my head hurt.

Why not just do something along these lines?

if ((length >= 2+BYTES_PER_TILE) && (buf[0] == CONST1) && (buf[1] == CONST2)) {
    for (char *tile = &buf[2]; tile < &buf[length-BYTES_PER_TILE]; tile+=BYTES_PER_TILE) {
        apply_surface(tile[0],tile[1],tiles,screen,&clip[tile[2]]);
    }
}
ndim
I'm a new programmer, but i'll have a look at that code and see if I can use it to optimize my program a little, thankyou!
ashrossy