Blackout: Stack oder "Listen"



  • Hi,

    Ich mache gerade das:
    http://www.pronix.de/pronix-829.html

    und bin mir nicht sicher, ob ich das auch richtig verstanden habe.

    Hier ist meine verkleinerte stackinit-funktion:

    int stackinit(void)
    {
        if( (stack_ptr=(struct person*)malloc(sizeof(struct person))) != NULL)
        {
           stack_ptr->next = NULL;
           strcpy(stack_ptr->name, "nix");
           stack_ptr->id = 0;
           return 1;
        }
        else
        {
            return 0;    
        }
    }
    

    Meine Beschreibung: Hier werden 1024 Bytes für die structs allokiert. Pro Struct braucht es 32 Bytes, also können 32 Einträge maximal gepusht werden?

    Problem Nr. 2:
    Funktion 'push()'

    int push(struct person *new)
    {
        new->next = stack_ptr->next;
        stack_ptr->next=new;
        return 1;    
    }
    

    Meine Beschreibung:

    In der neuen Struktur Var 'next' wird die Adresse vom aktuellen-next gespeichert. Danach erhält die neue Struct 'new' die Adresse vom aktuellen-next-pointer (bzw. Ziel, dort wo er hinzeigt).

    Jetzt muss doch noch irgendwie stack_ptr geupdatet werden, sonst bleibt das ding ja stehen.

    Kapiers da einfach nicht ganz, versteht ihr mein Problem? So ungefähr weiss ich schon was passiert, aber ich möchte es genau wissen mit allen Hintergründen etc.

    danke,
    Blackiartos



  • Blackiartos schrieb:

    Meine Beschreibung: Hier werden 1024 Bytes für die structs allokiert. Pro Struct braucht es 32 Bytes, also können 32 Einträge maximal gepusht werden?

    Wie kommst du darauf? Ich seh da nichts von 1024 oder 32. Da wird Speicher für eine struct Person alloziert, mehr nicht. Die anderen Personen werden jeweils genauso mit malloc alloziert und per push mit der Liste verbunden.

    *** EDIT: Hier stand Unsinn 🙂 ***



  • Blackiartos schrieb:

    Hier ist meine verkleinerte stackinit-funktion:

    int stackinit(void)
    {
        if( (stack_ptr=(struct person*)malloc(sizeof(struct person))) != NULL)
        {
           stack_ptr->next = NULL;
           strcpy(stack_ptr->name, "nix");
           stack_ptr->id = 0;
           return 1;
        }
        else
        {
            return 0;    
        }
    }
    

    Meine Beschreibung: Hier werden 1024 Bytes für die structs allokiert. Pro Struct braucht es 32 Bytes, also können 32 Einträge maximal gepusht werden?

    Falsch - du reservierst Platz für genau eine struct (und speicherst deren Adresse in stack_ptr).

    Problem Nr. 2:
    Funktion 'push()'

    int push(struct person *new)
    {
        new->next = stack_ptr->next;
        stack_ptr->next=new;
        return 1;    
    }
    

    Meine Beschreibung:

    In der neuen Struktur Var 'next' wird die Adresse vom aktuellen-next gespeichert. Danach erhält die neue Struct 'new' die Adresse vom aktuellen-next-pointer (bzw. Ziel, dort wo er hinzeigt).

    Soweit ist das richtig.

    Jetzt muss doch noch irgendwie stack_ptr geupdatet werden, sonst bleibt das ding ja stehen.

    Das machst du doch auch mit der Zeile "stack_ptr->next = new;" (das erste Element des Stacks bleibt immer der Dummy, den du in der init-Funktion angelegt hast)



  • Hi

    Ich habe gemerkt, dass es keinen Sinn macht, wenn ich von den herkömmlichen Listen noch keine Erfahrung habe.

    Hier ein Beispiel:

    #include <stdio.h>
    #include <stdlib.h>
    
    struct pers 
    {
        int tel;
        char name[20];  
    
        struct pers *next;
    };
    
    //To define next and beginning
    struct pers *next = NULL;
    struct pers *begin = NULL;
    
    void add(int t, char n[]) //t = tel, n = name
    {
        struct pers *ptr;
    
        if(begin == NULL)
        {
            /* we allocate memory for the first element in list */
            if( (begin = (struct pers*)malloc(sizeof(struct pers))) == NULL)
            {
                    fprintf(stderr, "No memory place for 'begin' found!\n");
                    return;
            }    
    
            /* save first element of the list */
            begin->tel = t;
            strcpy(begin->name, n);
            begin->next = NULL;
        }
        else
        {
            /* there is already the first placed */
            ptr = begin;
    
            /* Go to the last existing element */
            while(ptr->next != NULL)
              ptr=ptr->next;
    
            if( (ptr->next = (struct pers*)malloc(sizeof(struct pers))) == NULL)
            {
                    fprintf(stderr, "Cannot allocate more memory.\n");    
                    return;
            }
            ptr=ptr->next; //point to next memory place
            ptr->tel = t;
            strcpy(ptr->name, n);
            ptr->next = NULL;
        }
            free(ptr);
    }
    
    void printl(void)
    {
        struct pers *ptr;
    
        ptr = begin; //nur mit dieser Zeile kommt "Mueller"
        ptr = begin->next; //hier sollte "Hackbarth" kommen, kommt aber 0...
    
            printf("tel: %d\n", ptr->tel);
            printf("name:%s\n", ptr->name);
    
        ptr = NULL;
    }
    
    int main(int argc, char *argv[])
    {
        add(218, "Mueller");
        add(272, "Hackbarth");
        add(270, "Sesam");
    
        printl();
        system("PAUSE");	
        return 0;
    }
    

    Was für einen Denkfehler mache ich?
    Danke



  • Blackiartos schrieb:

    Was für einen Denkfehler mache ich?

    Du rufst am Ende der add()-Funktion "free(ptr);" auf - und löschst damit das Element, das du gerade in die Liste eingefügt hast.

    (PS: Für das Kopieren der Namen würde ich strncpy() vorschlagen)



  • hi

    CStoll (off):

    strncpy: BO's 😉

    Betreffend free(..). Das funktioniert jetzt.. sollte man aber nicht immer wieder den Speicher freigeben, d.h. am Ende des Programms, wie könnte ich das Realisieren... ode rsoll ich drauf sch**** (sorry für die Ausdrucksweise)?

    greezzZZz



  • Blackiartos schrieb:

    Betreffend free(..). Das funktioniert jetzt.. sollte man aber nicht immer wieder den Speicher freigeben, d.h. am Ende des Programms,

    Ja, solltest, du - aber erst wenn du ihn wirklich nicht mehr benötigst.

    wie könnte ich das Realisieren... ode rsoll ich drauf sch**** (sorry für die Ausdrucksweise)?

    Indem du die komplette Liste durchgehst und alle Elemente löschst:

    void clear()
    {
      struct pers* ptr=begin;//Hilfszeiger - merkt sich "altes" Anfangselement
      while(begin!=NULL)
      {
        begin=begin->next;   //schiebt Listenanfang weiter
        free(ptr);           //löscht bisheriges Anfangselement
        ptr=begin;           //schiebt Hilfszeiger weiter
      }
    }
    

    (aufzurufen aus der main() unmittelbar vor dem "return 0;")



  • Hi CStoll,

    Ey cool ;). Vielen Dank für deine freundliche und sehr rasche kompetente Hilfe.

    Wünsch nen guten Hunger

    gruss Blackiartos


Anmelden zum Antworten