[erledigt]Problem mit Bilder laden und strcmp



  • Hallo Leute!

    Ich versuche derzeitig, einen Magier vollständig für eine Animation zu laden. Dafür habe ich eine Ressourcen-Datei, die Graphiken etc. verwalten soll. Zu ihr gehört u.a. die Funktion zum Bilder laden:

    graphikinfo ress::hinzrs(char rs[256])  
    {  
      std::cout  << "ress::hinzrs rs : " << rs << std::endl;  
    
      SDL_WM_SetCaption(rs,0);  
    
      graphikinfo tinfo;  
      for (int i=0;i<maxid;++i)  
      {  
        std::cout << "ress::hinzrs rsarray["<<i<<"].name : " << rsarray[i].name << std::endl;  
    
        if (strcmp(rsarray[i].name,rs)==0 )  
        {  
          std::cout << "gleich"  << std::endl;  
          tinfo.graphikid=i;  
          tinfo.breite=rsarray[i].breite;  
          tinfo.hohe=rsarray[i].hohe;  
          return tinfo;  
        }  
      }
      SDL_Surface *temp;
      temp=SDL_LoadBMP(rs);
      if (temp==NULL) throw *SDL_GetError();
      rsarray[maxid].RS=temp;
      rsarray[maxid].hohe=temp->h;
      rsarray[maxid].breite=temp->w;
      rsarray[maxid].name=rs;
      SDL_SetColorKey(rsarray[maxid].RS, SDL_SRCCOLORKEY, SDL_MapRGB(rsarray[maxid].RS->format, 255, 0, 255));
      ++maxid;
    
      tinfo.graphikid=maxid-1;
      tinfo.hohe=temp->h;
      tinfo.breite=temp->w;
    
      return tinfo;
    }
    

    Insbesondere interresant ist dabei die Schleife am Anfang, sie sollte gleiche Bilder rausfiltern und so Speicher effektiver nutzen.

    Nun versuche ich, eine Magieranimation vollständig zu laden:

    for (int i=3;i<13;++i)
      {
        sprintf(buffer, "daten/magier/magic spelling se%04i.bmp", i);
        SDL_WM_SetCaption(buffer,0);
        G[i]=R->hinzrs(buffer);
    
      }
    

    Mein Problem: es läd immer nur einen Magier, und dann wird dieser als gleich erkannt.

    Die Testeingaben, die oben aufgeführt sind, geben folgendes aus(Bilder 1-3 werden anders geladen):

    stdout.txt schrieb:

    ress::hinzrs rs : daten/magier/magic spelling se0004.bmp
    ress::hinzrs rsarray[0].name : daten/magier/magic spelling se0001.bmp
    ress::hinzrs rsarray[1].name : daten/magier/magic spelling se0002.bmp
    ress::hinzrs rsarray[2].name : daten/magier/magic spelling se0003.bmp
    ress::hinzrs rs : daten/magier/magic spelling se0005.bmp
    ress::hinzrs rsarray[0].name : daten/magier/magic spelling se0001.bmp
    ress::hinzrs rsarray[1].name : daten/magier/magic spelling se0002.bmp
    ress::hinzrs rsarray[2].name : daten/magier/magic spelling se0003.bmp
    ress::hinzrs rsarray[3].name : daten/magier/magic spelling se0005.bmp
    gleich

    Seltsamerweise wird hier zwar der richtige Name übergeben, aber die 4 scheint aus dem Speicher gelöscht zu sein, obwohl sie doch mit

    rsarray[maxid].name=rs;
    

    hereingeschrieben sein sollte.

    Hat jemand eine Ahnung, wo der Fehler liegt? Ich beiße mir jetzt schon seit gestern Abend die Zähne daran aus...



  • welcher typ ist

    rsarray[maxid].name
    

    ? zufaellig const char*?



  • Dieser Thread wurde von Moderator/in rapso aus dem Forum Spiele-/Grafikprogrammierung in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Nein, ein ganz normaler char*. Er gehört zu folgendem struct:

    struct intern_graphikinfo
    {
      int graphikid, hohe, breite;
      char *name;
      SDL_Surface *RS;
    };
    


  • warum arbeitest du nicht durchgehen mit Standard-Lib? => std::string ...
    hast insgesammt viele möglichkeiten für Speicherüberläufe drin ..



  • Das wäre in diesem Fall nicht großartig sinnvoll, zumindest am Ort des eigentlichen Fehlers. Denn SDL_LoadBMP nimmt nun mal nen char*, und keinen std::string. Und ob ich nun strcmp(rs, rsarray[i].name) oder rs==rsarray[i].name schreibe ist ja nicht weiter wichtig.
    Das Problem ist ja wahrscheinlich irgendwo in der Verwaltung des Arrays oder so...oder um ehrlich zu sein, ich hab keinen Plan, wo der Fehler liegt, deshalb hab ich ja hier das Thema verfasst...



  • guck mal, hättest du std::string genommen, wäre dir DAS nicht passert 🙂

    Als Parameter übergibst du ein char-array, das ist eigentlich ein char*. Der Zeiger ist gültig, bis die Funktion wieder verlassen wird. In der Funktion weißt du mit

    rsarray[maxid].name=rs;

    deinem länger lebenenden Array die Addresse! des Namens zu. Du kopierst also nicht den Namen, sondern nur die Adresse. Wenn die funktion verlassen wird, zeigt rsarray[maxid].name sonstwohin und enthält nicht mehr deinen Namen.

    Lösung:

    struct intern_graphikinfo
    {
      int graphikid, hohe, breite;
      char name[512];   // hier muss der speicher selbst reserviert werden, damit er bleibt und nciht bei funktionsende weggeht
      SDL_Surface *RS;
    };
    // in funktion:
    //anstatt 
    rsarray[maxid].name=rs;
    
    // das hier:
    strcpy(rsarray[maxid].name, rs);
    

    Aber nochmal: Nimm std::string, das is viel besser. Damit hast du soen probleme nciht mehr, weil die kopierkonstruktor hat und alles in ordnung ist. Und wenn SDL_LoadSonstwas einen char* erwartet, dann machst du einfach ein string::c_str() und schon hast du deinen char*.

    Also, weg vom char*, hin zum std::string 🙂



  • Danke, das war natürlich die Lösung 🙂

    Hab schon damit begonnen, std::string zu lernen, so grob, aber komplett meine Programme umstellen wird wohl noch ein bisschen dauern...



  • die zeit diese grundlagen zu lernen solltest du dir nehmen, sonst wirst du weiterhin diese fehler haben die dich unnoetig aufhalten (und viel mehr zeit kosten als ein wenig lernen).


Anmelden zum Antworten