Problem mit verketteter List



  • Hi, ich hab da irgendwie ein Problem mit meiner verketteten Liste.
    Habe die in der Konsolenanwendung ganz normal geschrieben, wollte die nun aber in meiner WinAPI Anwendung mit String(std::..) benutzen und hab evrsucht sie umzubauen.
    diese funktioniert aber irgendwie nicht 😞
    nach ein bisschen google-nutzen kam ich auf ein vordefiniertes List aus der STL.

    kann ich mit diesem List auch einfach ne liste machen? Habe leider weder zur verwendung von List (für verkettete listen) noch ein einfaches beispiel/tutorial zum Listen ertsellen mit std:string gefunden.

    kann mir evtl jemand weiterhelfen bzw hat ein tutorial?

    meine liste, bzw die struktur, hat im grunde nur 2 Int-Variablen und 1 String-Variable(und halt den Zeiger auf den nächsten eintrag).

    als ich das ganze noch mit char, char* machte ging es super, nur halt jetzt nicht mehr 😞

    hab da auch schon verschiedenste versuche gemacht aber es kommen immer fehler bei ner z.b. wertzuweisung und son zeuch.

    typedef struct ListItem
    {
    	std::string Textur;
    	int iPos;
    	int index;
    	struct ListItem *next;
    } List;
    

    das is meine struktur dazu.
    wenn ich nun was einfügen will sieht das so aus:

    int ListAdd(List **pp_list, int iPos, std::string Textur, int index)
    {
    	List *pNewElement;
    	List *temp;
    	temp=*pp_list;
    	FILE *fFile;
    	fopen_s(&fFile, "info.txt", "w+");
    //	while(temp!=NULL)
    //	{
    //		if(temp->Textur==Textur)
    //			return 0;
    //		temp=temp->next;
    //	}
    	fprintf(fFile, "Info-File\n");
    	fprintf(fFile,"iPos: %i\n", (*pp_list)->iPos);
    	if((*pp_list)->Textur.empty())
    	{
    		(*pp_list)->iPos=iPos;
    		(*pp_list)->index=index;
    		(*pp_list)->Textur.assign(Textur.c_str());
    		return 0;
    	}
    	fclose(fFile);
    	pNewElement=new List;
    	if(pNewElement==NULL)
    		return 1;
    	else
    	{
    		(*pp_list)->Textur.assign(Textur.c_str());
    		(*pp_list)->iPos=iPos;
    		(*pp_list)->index=index;
    		pNewElement->next=*pp_list;
    		*pp_list=pNewElement;
    		return 0;
    	}
    	return 0;
    }
    

    aber es gibt schon macken beim zuweisen.
    z.b. kommt während der runtime ein absturtz
    habe haltepunkt nach der 1. if schleife gesetzt, beim "}",
    also die zeile bevor pNewelement speicherplatz bekommt.

    ist so ein "Debug Assertion Failed" bild mit Expression: str!=NULL

    aber kann mir das absolut nicht erklären da auch keiner verweis auf eine zeile kommt



  • Eroda schrieb:

    ... nach ein bisschen google-nutzen kam ich auf ein vordefiniertes List aus der STL.

    kann ich mit diesem List auch einfach ne liste machen?

    Ja - einfach std::list< Item > (erfordert #include <list>)

    Eroda schrieb:

    .. als ich das ganze noch mit char, char* machte ging es super,

    😃 Herb Sutter sagt dazu: "nackt über das Minenfeld laufen" manchmal geht es gut ...

    Eroda schrieb:

    nur halt jetzt nicht mehr 😞

    .. und manchmal nicht.

    Wenn Du Dein Item so umbaust und z.B. auch mit Konstruktoren versiehst:

    struct Item
    {
        Item() : Textur(), iPos(), index() {}
        Item( const std::string& Textur_, int iPos_, int index_ )
            : Textur( Textur_ ), iPos( iPos_ ), index( index_ ) 
        {}
        std::string Textur;
        int iPos;
        int index;
    };
    

    dann reduziert sich das ListAdd zu:

    int ListAdd( std::list< Item >& list, int iPos, const std::string& Textur, int index)
    {
        list.push_back( Item( Textur, iPos, index ) );
        return 0;
    }
    

    .. bzw. Du brauchst es gar nicht mehr.

    Der Aufruf sähe dann etwa so aus:

    int main()
    {
        using namespace std;
        std::list< Item > list;
        ListAdd( list, 1/*iPos*/, "Textur", 5/*index*/ );
    
        // bzw.:
        Item item( "Textur2", 3, 12 );
        list.push_back( item );
    
        cout << "Die Liste enthält " << list.size() << " Elemente" << endl;
        return 0;
    }
    


  • Sry, bin da grad etwas verwirrt da ich zum Thema List nix passendes gefunden hab.

    Also, um die verkettete Liste zu umgehen baue ich einfach nen konstruktor in meine struktur rein und lade dann so ein strukturelement einfach in eine variable vom typ List?
    und List übernimmt dann das ganze Listen management wie halt in liste einfügen, anzeigen/wiedergeben aller inhalte etc.



  • Ich wollte Dich nicht verwirren - Der Konstruktor hat mit der List-Geschichte zunächst nichts zu tun, erleichtert aber die Schreibarbeit bei der Anwendung.
    Eine Referenz zur std::list findest Du hier.



  • ah, okay. super 🙂
    mit ein bisschen versuchen und hin udn ehr ging das soweit 🙂
    nun nur noch schaun wie ich die texturen lade und schon passt es 🙂

    (btw das ding soll *.3ds dateien laden, bevor sich wer wundert was ich hier mache oO )



  • Ich seh da noch nen Haufen anderer Sachen, die entstehen, wenn man als C-Programmierer C++ Programme schreibt:

    - new gibt NIEMALS 0 zurück, es sei denn, man spezifiert (NOTHROW). Wenn der Aufruf fehlschlägt wird bad_alloc geworfen, aber es wird keine 0 zurückgegeben. Der Check gegen 0 macht überhaupt keinen Sinn da der Code im Fall eines Fehlschlags nie erreicht wird.

    - std::string unterstützt Vergleichsoperatoren, statt strcmp() kann man zwei std::strings direkt mit == vergleichen

    - std::string unterstützt den Zuweisungsoperator, statt assign kann man einem String per = einen neuen Inhalt zuweisen

    - typedef struct { ... } Name ist ein C Relikt, in C++ wird das Schlüsselwort struct genauso verwendet wie class

    - FILE ist ebenso ein C Relikt, in C++ verwendet man iostreams. Zudem vergisst du an einigen Stellen die Datei zu schliessen, weil du mit return vorzeitig die Funktion verlässt

    - die ganze Konvertiererei von std::string nach const char* und zurück ist überflüssig... übergib einfach const Referenzen auf std::string.

    - warum gibt deine Funktion ListAdd einen numerischen Wert zurück, wenn das Ergebnis entweder true oder false ist?

    Und zu guter Letzt:
    Das alles lässt sich durch std::map<std::string, std::string> ersetzen.

    #include <map>
    #include <string>
    
    int main()
    {
       std::map<std::string,std::string> Substitution;
       // map wird irgendwie gefüllt
    
       std::string TexturName = "Material_02";
    
       std::map<std::string,std::string>::const_iterator pos = Substitution.find( TexturName );
       if( Substitution.end() != pos )
       {
          TexturName = pos->second;
       }
    }
    

    Ich bin immer wieder erschrocken, mit welchem Code Leute hier auftauchen, bzw. was ihnen heutzutage noch beigebracht wird. Man sollte sich schon entscheiden, ob man C oder C++ programmieren möchte, aber bitte bitte bitte nicht beides vermischen. Nimm´s bitte nicht persönlich.



  • danke für die ganzen tips.
    und nein, ich nehme es nicht persönlich.

    ine meinr schule wurde mit stumpf ansi c beigebracht und wenn man dsa ne recht lange zeit macht wird der umstiegf nach udn nach schwerer.
    aber naja, muss man das beste draus machen.

    hab nach und nach auch schon einige c-überreste rausgehaun wie nun das strcmp und so aber danke nochmal für den hinweis.

    aber ich hätte da nochmal ne frage.
    ich möchte ein bestimmtes bild laden um das mit opengl als textur nutzen zu können.
    nun möchte ich deswegen aber kein sdl-surface machen(und auch ka ob das so easy funzen würde, da ich ja diesmal kein sdl für video nutze)
    die sache mit AUX_RGBImageRec zu machen, woltle ich eg auch ablehnen da diese art ja, nach dem ich das ein oder andere drüber gelesen hab, recht zeitaufwendig ist.

    gibts den da noch ne alternativ?


Anmelden zum Antworten