Was ist das Problem? (Listen in C)



  • Hallo, ich habe ein Problem beim Ausführen von meine Code:

    /*
     * Funktion: Beispiel einer einfach verketteten Liste (mit einfügen hinten)
     */
    
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    
    typedef struct ELEMENT
    { 
    	struct ELEMENT *n; // Zeiger auf das nächste Listenelement
    	int inhalt;
    } Element;
    
    /*typedef struct LISTENKOPF
    {
    	struct LISTENKOPF *erstes; //Zeiger auf das 1. Listenelement
    	int anzahl;
    } Listenkopf;*/
    
    void ListeAufbauen(Element *kopf, Element *ende, Element *p, int i);
    void ElementLoeschen(Element *p, Element *kopf, Element *loesch, int gone, int i);
    void ElementEinfuegenDazwischen(Element *p, Element *kopf);
    void ListeAusgeben(Element *p, Element *kopf);
    
    void main()
    { 
    	Element *p, *ende, *loesch, *kopf;
    	int i, auswahl, gone;
    
    	i = auswahl = gone = 0; //Schleifenzähler mit 0 initialisieren
    	kopf = ende = loesch = p = NULL; //Alle nötigen Zeiger zeigen nun auf NULL
    
    	ListeAufbauen(kopf, ende, p, i);
    	ElementLoeschen(p, kopf, loesch, gone, i);
    	ElementEinfuegenDazwischen(p, kopf);
    	ListeAusgeben(p, kopf);
    }
    
    void ListeAufbauen(Element *kopf, Element *ende, Element *p, int i)
    {
    	int zahl;
    
    	printf("%d.Listenelement: " ,++i);
    	scanf("%d", &zahl);
    
    	while(zahl != 0)
    	{ 
    		p = (Element*)malloc(sizeof(Element));
    
    		if (p != NULL) //Wenn die Speicherallokierung erfolgreich war
    		{ 
    			p->inhalt=zahl;
    
    			if(kopf==NULL) //Wenn Liste leer (=wenn noch kein Element eingelesen wurde)
    			{
    				kopf=p;
    				ende=p;
    				p->n=NULL;
    			}
    
    			else //Wenn Liste nicht leer (normalerweise nach einlesen des 1. Elementes)
    			{
    				ende->n=p;
    				p->n=NULL;
    				ende=ende->n;
    			}
    
    			printf("%d.Listenelement: " ,++i);
    			scanf("%d", &zahl);
    		}
    
    		else //Wenn kein Speicherplatz reserviert werden konnte
    		{ 
    			printf("\nZu wenig Speicherplatz");
    			break;
    		}
    	}
    }
    
    void ElementLoeschen(Element *p, Element *kopf, Element *loesch, int gone, int i)
    {
    	int loeschNr;
    
    	p = kopf; //p auf das 1. Element setzen
    
    	printf("\nWelches Element soll geloescht werden?");
    
    	printf("\nEingabe: ");
    	scanf("%d", &loeschNr);
    
    	while(loeschNr != p->inhalt)
    	{
    		p = p->n;
    
    		gone++; //Anzahl der Weiterschaltungen wird mitgezählt
    	}
    
    	p = kopf;
    
    	for(i=1; i<=gone-1; i++)
    	{
    		p = p->n;
    	}
    	//p zeigt nun auf das Element vor dem zu löschendem Element
    
    	if(loeschNr == p->inhalt) //Wenn die zu löschende Zahl das 1. Element ist
    	{
    		loesch = p;
    		p = p->n;
    	}
    
    	loesch = p->n; 
    	p->n = loesch->n;
    	free(loesch);
    }
    
    void ElementEinfuegenDazwischen(Element *p, Element *kopf)
    {
    	Element *newElement, *vorgaenger, *nachfolger;
    	int vorgaengerNr;
    
    	vorgaenger = nachfolger = NULL;
    
    	p = kopf;
    
    	newElement = (Element*)malloc(sizeof(Element));
    
    	printf("\n\nNeues Element: ");
    	scanf("%d", &newElement->inhalt);
    
    	printf("Nach welchem Element soll das neue Element eingefuegt werden?");
    
    	printf("\nVorgaenger: ");
    	scanf("%d", &vorgaengerNr);
    
    	while(vorgaenger != p->inhalt)
    	{
    		vorgaenger = p->n;
    	}
    
    	//vorgänger wurde gefunden
    
    	vorgaenger = p;
    	nachfolger = p->n;
    
    	vorgaenger->n = newElement;
    	newElement->n = nachfolger;
    }
    
    void ListeAusgeben(Element *p, Element *kopf)
    {
    	printf("\n\nAusgabe der Liste (eventuell wurden Elemente hinzugefuegt)\n\n");
    
    	p = kopf;
    
    	while(p != NULL)
    	{ 
    		printf("%d\n" , p->inhalt);
    		p = p->n;
    	}
    
    	getch();
    }
    

    Sobald ich das zu löschende Element eingegeben habe und Enter gedrückt habe, stürzt das Programm ab. (mit irgend so einem typischen Adressenfehler,...)

    "This is the next statement to execute when this thread returns from the current function" steht dann in Zeile Nr. 93

    Bitte um Hilfe 😞

    PS: Hab schon alles versucht, das ganze (wie immer) auf ein Blatt Papier aufgezeichnet, etc...hilft aber alles nix (laut meinen Zeichnungen sollte das Programm an sich funktionieren....wenn da dieser Absturz nicht wäre... 😉 )



  • Nimm den Debugger.

    Oder schreib mal

    //vorZeile 35:
    printf("vor  ListeAufbauen: kopf: %p, ende: %p, p: %p, i: %d\n", kopf, ende, p, i); 
    ListeAufbauen(kopf, ende, p, i);   // Zeile 35
    //nach Zeile 35:
    printf("Nach ListeAufbauen: kopf: %p, ende: %p, p: %p, i: %d\n", kopf, ende, p, i);
    

    Schau mal nach ob das die Werte sind, die du erwartest.



  • Naja der Debugger bringt logischerweise nicht viel, wieso sollte er auch? Habs ja ganze Zeit mit dem Debugger ausgeführt, wie denn sonst? 😉

    Ok hab das mit den printf's mal eingefügt...vorher ist alles "0" bzw. "0.0000000"....nachdem die Liste aufgebaut wurde ist auch alles "0", außer in "ende" steht irgendeine große Zahl...

    Was kann ich daraus schließen?

    Danke 😉



  • kopf zeigt immer noch auf NULL.
    Du bekommst den Wert von kopf nicht aus ListeAufbauen zurück.

    Da du in den weitern Funktionen aber kopf == NULL nicht abfängst, stürzt dein Programm ab.

    Wie bekommst du jetzt kopf zurück?
    Entweder du machst aus kopf einen Doppelzeiger oder
    du gibst kopf als Rückgabewert deiner Funktion an. (Also nicht mehr void)



  • Achsoooo ist ja eigentlich logisch:

    Das 1. UP funktioniert ja noch, da ich zuerst kopf mit NULL initialisiere und dann verwende. Aber im 2. UP übergebe ich ja noch immer den kopf, der mit "NULL" initialisiert ist...alles klar ich versuch das mal danke 😉



  • Ok, hab die UP jetzt statt void vom Typ "Element*" gemacht.

    Jetzt kann ich wenigstens ohne Absturz das zu löschende Element einlesen. Aber nach dem einlesen geschieht einfach nichts....

    was ist da los?



  • Was passiert denn bei

    printf("vor  ListeAufbauen: kopf: %p, ende: %p, p: %p, i: %d\n", kopf, ende, p, i);
    
    ListeAufbauen(kopf, ende, p, i);  
    printf("Nach ListeAufbauen: kopf: %p, ende: %p, p: %p, i: %d\n", kopf, ende, p, i); 	
    
    // ElementLoeschen(p, kopf, loesch, gone, i);
    // ElementEinfuegenDazwischen(p, kopf);
    
    ListeAusgeben(p, kopf);
    

    Also nur aufbauen und ausgeben. Ohne löschen.



  • Dann gibt das Programm nachdem ich 0 eingebe in eine Endlosschleife ganze Zeit irgend eine Speicheradresse aus... 😞



  • Warum steppst Du nicht mit dem Debugger durch und guckst Dir die Werte an?
    Dann kannst Du auch nachschauen warum Dein Abbruchkriterium nicht zieht.



  • Hast du auch in ListeAufbauen ein

    return kopf;
    

    ?

    Und rufst du es mit

    kopf = ListeAufbauen([t]Deine Variablen hier[/t]);
    

    auf?


Anmelden zum Antworten