2010-09-29 6 views
2

Je suis un programmeur assez récent, mais je considère que mon google-fu est assez compétent et j'ai passé plusieurs heures à chercher. J'ai une simple application SDL qui lit à partir d'un fichier binaire (2 octets comme un nombre magique, puis 5 octets par "tuile") puis affiche chaque tuile dans le tampon, les octets décident le x, y, id, passability et autres. Donc, c'est vraiment le chargement de niveau.Fichiers lus différemment sous Linux? C++

Il fonctionne bien sur n'importe quel ordinateur Windows (testé Windows Server 2008, 7/64 et 7/32) mais quand je compile sur Linux, il affiche des carreaux aléatoires dans des positions aléatoires. Je serais tenté de dire qu'il lit la mauvaise partie de la RAM, mais j'ai implémé le nombre magique afin qu'il renvoie une erreur si les 2 premiers octets étaient sortis. J'aimerai bien m'en rendre compte moi-même mais ça m'embête maintenant et je ne peux pas progresser plus longtemps à moins de pouvoir programmer en déplacement (mon ordinateur portable fonctionne sous Linux). J'utilise G ++ sur Linux, mingw32g ++ sur 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; 
} 

Merci d'avance!

+1

Veuillez poster le code. Il semble probable que vous avez fait des suppositions sur la façon dont le compilateur va faire les choses; différentes plates-formes ont (légèrement) différentes conventions sur des choses comme l'emballage de la structure. Postez le code et quelqu'un le comprendra rapidement. – MarkR

+0

Vous pouvez inclure les compilateurs que vous utilisez sur chaque plate-forme. – sleepynate

+0

J'ai mis à jour le code avec des informations plus pertinentes – sudorossy

Répondre

5

La gestion de votre tableau est incorrecte.
L'indexation de tableau en C/C++ commence à 0.

Vous avez défini 'tile_buffer' comme taille de tableau 'BYTES_PER_TILE'.
Si BYTES_PER_TILE était 5, votre tableau aurait les éléments tile_buffer [0] à tile_buffer [4].

Dans votre boucle for interne, vous effectuez une boucle de 1 à 5 de sorte qu'un débordement de tampon se produise.

Je ne sais pas si c'est la cause de votre problème, mais cela ne va certainement pas aider les choses.

+0

Merci, la réparation du code a résolu le problème! Je me demande pourquoi cela a fonctionné correctement sur Windows. – sudorossy

0

Ce n'est probablement pas une réponse, mais la gestion de la matrice basée sur 1 et la copie inutile ont fait mal à ma tête. Pourquoi ne pas simplement faire quelque chose dans ce sens?

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]]); 
    } 
} 
+0

Je suis un nouveau programmeur, mais je vais regarder ce code et voir si je peux l'utiliser pour optimiser mon programme un peu, merci! – sudorossy