Files reading differently in linux? C++
Question
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!
Solution
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.
OTHER TIPS
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]]);
}
}