Compilerfehler dereferencing pointer to incomplete type ‘struct Warteschlange’|



  • Dankeschön!

    Ich habs überhaupt nicht gesehen.

    Der Code soll ja erst einmal funktionieren, Linux Haut mir da z. B. auch noch Speicherzugriffsfehler, vermutlich Nullzeiger o. Ä., raus. Ist also noch nicht fertig und auch noch nicht vernünftig kommentiert.

    Oder meintest du da jetzt was spezielles?


  • Mod

    HansKlaus schrieb:

    Der Code soll ja erst einmal funktionieren,

    Linux Haut mir da z. B. auch noch Speicherzugriffsfehler, vermutlich Nullzeiger o. Ä., raus.

    Zwischen den beiden Aussagen besteht ein Zusammenhang. Wenn du nicht sauber programmierst und dir keine echte Mühe gibst, dann ist klar, dass da nichts funktionierendes bei raus kommt.

    Deinem Code kann man sofort ansehen, dass er schnell hingeschludert wurde.



  • Also die Aufgabe lautet, eine Mensa zu simulieren, in die mehrere Studenten-Threads gehen, sich in die Warteschlange der Essensausgabe einreihen und warten, bis sie an der Reihe sind, die Essensausgabe zu sperren, dann eine zufällige Zeit warten, bis sie das Essen bekommen haben und sich danach in die Warteschlange der Kassen einreihen, um dann wieder zu warten, bis sie an der Reihe sind, um an eine von vier Kassen zu kommen, dann wieder die jeweilige Kasse sperren, eine zufällige, jedoch durchschnittlich längere Zeit an der Kasse zu stehen, und dann sollen sie sich wieder beenden.

    Naja und das habe ich dann umzusetzen versucht, mit sperrvariable, einer zusätzlichen Überprüfung und eben mit zeigervariablen. Es fehlt ja z. B. auch noch ein Free auf studentdata.



  • HansKlaus schrieb:

    =(*(*(*
    

    HansKlaus schrieb:

    Der Zugriff auf wsausgabe weiter oben funktioniert komischerweise. 😕



  • (*pointer_auf_struct).element == pointer_auf_struct->element



  • syntactic sugar schrieb:

    (*pointer_auf_struct).element == pointer_auf_struct->element

    Das weiß ich. Aber pointer_auf_struct->(pointer_in_struct) geht z.b. nicht,
    (
    (*pointer_auf_struct).pointer_in_struct) dagegen schon.

    weiß eigentlich jemand, wie ich Dinge wie pointer_auf_struct->array_in_struct[3] nur unter Verwendung von Dereferenzierungs-Operatoren mache? Also irgendwas im Sinne von (*(*struktur).(zeiger+3))?

    Der Code funktioniert übrigens soweit ich das beurteilen kann. 😃



  • ////////////////////////////////////////////////////////////////
    //Ralf Peglow
    //Matr. Nr.: 914410
    //Übung 6 Aufgabe 1
    ////////////////////////////////////////////////////////////////
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    struct WarteSchlange
    {
        struct StudentData *first;
        struct StudentData *last;
    };
    
    struct StudentData
    {
        int id;
        int wartezeit_ausgabe;
        int wartezeit_kasse;
        struct WarteSchlange *wsausgabe;
        int *wsausgabe_blockiert;
        struct WarteSchlange *wskasse;
        int *wskasse_blockiert;
        struct StudentData *next;
        int *ausgabe;
        int *ausgabe_blockiert;
    
        //Funktioniert nicht
        /*
        int *kasse;
        int *kasse_blockiert;
        */
        int *kasse0;
        int *kasse1;
        int *kasse2;
        int *kasse3;
    
        int *kasse0_blockiert;
        int *kasse1_blockiert;
        int *kasse2_blockiert;
        int *kasse3_blockiert;
    };
    
    void *StudentProc(struct StudentData *studentdata);
    
    int main()
    {
        const int maxstuds=20;
        pthread_t studenten[maxstuds];
        int i;
        struct StudentData *studentdata;
        struct WarteSchlange wsausgabe;
        int wsausgabe_blockiert;
        struct WarteSchlange wskasse;
        int wskasse_blockiert;
        int ausgabe;
        int ausgabe_blockiert;
    
        //Funktioniert nicht.
        /*
        int *kasse;
        int *kasse_blockiert;
    
        kasse=(int*)malloc(sizeof(int)*4);
        kasse_blockiert=(int*)malloc(sizeof(int)*4);
    
        */
    
        int kasse0;
        int kasse1;
        int kasse2;
        int kasse3;
        int kasse0_blockiert;
        int kasse1_blockiert;
        int kasse2_blockiert;
        int kasse3_blockiert;
    
        wsausgabe.first=0;
        wsausgabe.last=0;
        wsausgabe_blockiert=0xFFFFFFFF;
    
        wskasse.first=0;
        wskasse.last=0;
        wskasse_blockiert=0xFFFFFFFF;
    
        ausgabe=0;
        ausgabe_blockiert=0xFFFFFFFF;
    
        //Funktioniert nicht.
        //Dies war ein Versuch, dynamisch alloziierte Datenbereiche an die StudentProc
        //zu übergeben und dann auf die einzelnen Elemente zuzugreifen
        /*
        *kasse=0;
        *kasse_blockiert=0xFFFFFFFF;
        *(kasse+1)=0;
        *(kasse_blockiert+1)=0xFFFFFFFF;
        *(kasse+2)=0;
        *(kasse_blockiert+2)=0xFFFFFFFF;
        *(kasse+3)=0;
        *(kasse_blockiert+3)=0xFFFFFFFF;
    
        */
        kasse0=0;
        kasse1=0;
        kasse2=0;
        kasse3=0;
        kasse0_blockiert=0xFFFFFFFF;
        kasse1_blockiert=0xFFFFFFFF;
        kasse2_blockiert=0xFFFFFFFF;
        kasse3_blockiert=0xFFFFFFFF;
    
        //Erstellen der Studenten-Threads
        for(i=0;i<maxstuds;i++)
        {
            //Dynamische Allokation der StudentData-Strukturen für die einzelnen
            //Studenten-Threads und Zuweisung der entsprechenden Werte
            studentdata=(struct StudentData*)malloc(sizeof(struct StudentData));
            (*studentdata).id=i;
            (*studentdata).wartezeit_ausgabe=rand()%5;
            (*studentdata).wartezeit_kasse=rand()%9;
            (*studentdata).wsausgabe=&wsausgabe;
            (*studentdata).wsausgabe_blockiert=&wsausgabe_blockiert;
            (*studentdata).wskasse=&wskasse;
            (*studentdata).wskasse_blockiert=&wskasse_blockiert;
            (*studentdata).next=0;
            (*studentdata).ausgabe=&ausgabe;
            (*studentdata).ausgabe_blockiert=&ausgabe_blockiert;
    
            //Funktioniert nicht
            /*
            (*studentdata).kasse=&kasse;
            (*studentdata).kasse_blockiert=&kasse_blockiert;
            */
    
            (*studentdata).kasse0=&kasse0;
            (*studentdata).kasse1=&kasse1;
            (*studentdata).kasse2=&kasse2;
            (*studentdata).kasse3=&kasse3;
            (*studentdata).kasse0_blockiert=&kasse0_blockiert;
            (*studentdata).kasse1_blockiert=&kasse1_blockiert;
            (*studentdata).kasse2_blockiert=&kasse2_blockiert;
            (*studentdata).kasse3_blockiert=&kasse3_blockiert;
    
            //Studenten-Threads erstellen
            pthread_create(&studenten[i],0,(void*)&StudentProc,studentdata);
        }
    
        //Threads wieder beenden
        for(i=0;i<maxstuds;i++)
        {
            pthread_join(studenten[i],NULL);
        }
    
        //Gibt an, welche der vier Kassen wie oft angelaufen wurde.
        printf("Geld in den Kassen:\n");
        printf("Kasse 0: %d\n",kasse0);
        printf("Kasse 1: %d\n",kasse1);
        printf("Kasse 2: %d\n",kasse2);
        printf("Kasse 3: %d\n",kasse3);
    
        return 0;
    }
    
    void *StudentProc(struct StudentData *studentdata)
    {
        printf("Student Nr. %d betritt die Mensa.\n",(*studentdata).id);
        //Student reiht sich in die Warteschlange der Ausgabe ein
        for(;;)
        {
            //Überprüfen, ob sich bereits ein anderer Student einreiht
            //bzw. ob die WarteSchlange gesperrt ist
            if((*(*studentdata).wsausgabe_blockiert)==0xFFFFFFFF)
            {
                //Setzen der Sperrvariable
                (*(*studentdata).wsausgabe_blockiert)=(*studentdata).id;
    
                //Überprüfen, ob nicht gleichzeitig ein anderer Thread die
                //Sperrvariable gesetzt hat
                if((*(*studentdata).wsausgabe_blockiert)==(*studentdata).id)
                {
                    if((*(*studentdata).wsausgabe).first==0)
                    {
                        //In diesem Fall ist die Warteschlange noch (bzw. wieder) leer
                        (*(*studentdata).wsausgabe).first=studentdata;
                        (*(*studentdata).wsausgabe).last=studentdata;
                    }
                    else
                    {
                        //In diesem Fall ist die Warteschlange nicht leer
                        (*(*(*studentdata).wsausgabe).last).next=studentdata;
                        (*(*studentdata).wsausgabe).last=studentdata;
                    }
    
                    printf("Student Nr. %d hat sich in die Warteschlange der Ausgabe eingereiht.\n",(*studentdata).id);
    
                    //Rücksetzen der Sperrvariable
                    (*(*studentdata).wsausgabe_blockiert)=0xFFFFFFFF;
                    break;
                }
            }
            //Aktives Warten
            usleep(1000);
        }
    
        //Student wartet, bis er an der Reihe ist
        for(;;)
        {
            if((*(*studentdata).wsausgabe).first==studentdata)
            {
                printf("Student Nr. %d steht in der Warteschlange der Ausgabe ganz vorne.\n",(*studentdata).id);
                break;
            }
            //Aktives Warten
            usleep(1000);
        }
    
        //Student wartet, bis Ausgabe frei ist
        for(;;)
        {
                //Überprüfen ob bereits ein anderer Student an der Essensausgabe steht
                //bzw. die Essensausgabe gesperrt ist
                if((*(*studentdata).ausgabe_blockiert)==0xFFFFFFFF)
                {
                    //Setzen der Sperrvariable
                    (*(*studentdata).ausgabe_blockiert)=(*studentdata).id;
    
                    //Überprüfen ob nicht zwischenzeitlich ein anderer Thread die
                    //Sperrvariable gesetzt hat.
                    if((*(*studentdata).ausgabe_blockiert)==(*studentdata).id)
                    {
                        //Nächsten Studenten an den Anfang der Warteschlange bewegen
                        (*(*studentdata).wsausgabe).first=(*(*(*studentdata).wsausgabe).first).next;
    
                        printf("Student Nr. %d steht an der Ausgabe.\n",(*studentdata).id);
    
                        //Student greift auf die gemeinsame Variable ausgabe zu.
                        (*(*studentdata).ausgabe)=(*(*studentdata).ausgabe)+1;
    
                        //Student wartet gemäß der Aufgabe auf sein Essen weil die gute
                        //Frau hinter der Theke mal wieder nicht in Wallung kommt
                        sleep((*studentdata).wartezeit_ausgabe);
                        printf("Student Nr. %d hat sein Essen bekommen und geht jetzt zur Kasse.\n",(*studentdata).id);
    
                        //Rücksetzen der Sperrvariable
                        (*(*studentdata).ausgabe_blockiert)=0xFFFFFFFF;
                        break;
                    }
                }
                //Aktives Warten
                usleep(1000);
        }
    
        //Student reiht sich in die Warteschlange der Kasse ein
       for(;;)
        {
            //Überprüfen ob sich bereits ein anderer Student iń die Warteschlange einreiht
            //bzw. die Warteschlange gesperrt ist.
            if((*(*studentdata).wskasse_blockiert)==0xFFFFFFFF)
            {
                //Setzen der Sperrvariable
                (*(*studentdata).wskasse_blockiert)=(*studentdata).id;
    
                //Überprüfen ob zwischenzeitlich ein anderer Thread die Sperrvariable gesetzt hat
                if((*(*studentdata).wskasse_blockiert)==(*studentdata).id)
                {
                    //Einreihen in die Warteschlange
                   if((*(*studentdata).wskasse).first==0)
                    {
                        //Hier ist die Warteschlange noch (oder wieder) leer
                        (*(*studentdata).wskasse).first=studentdata;
                        (*(*studentdata).wskasse).last=studentdata;
                    }
                    else
                    {
                        //Hier befinden sich bereits Threads in der Warteschlange
                        (*(*(*studentdata).wskasse).last).next=studentdata;
                        (*(*studentdata).wskasse).last=studentdata;
                    }
    
                    printf("Student Nr. %d hat sich in die Warteschlange der Kasse eingereiht.\n",(*studentdata).id);
    
                    //Rücksetzen der Sperrvariablen
                    (*(*studentdata).wskasse_blockiert)=0xFFFFFFFF;
    
                    break;
                }
            }
            usleep(1000);
        }
    
        //Student wartet wieder, bis er an der Reihe ist.
        for(;;)
        {
            if((*(*studentdata).wskasse).first==studentdata)
            {
                printf("Student Nr. %d steht in der Warteschlange der Kasse ganz vorne.\n",(*studentdata).id);
                break;
            }
            usleep(1000);
        }
    
        //Student möchte an eine der Kassen gehen
        for(;;)
        {
            //Überprüfen ob bereits ein Student an Kasse 0 bezahlt bzw. ob die
            //Sperrvariable für kasse0 gesetzt ist.
            if((*(*studentdata).kasse0_blockiert)==0xFFFFFFFF)
            {
                //Setzen der Sperrvariable für Kasse 0
                (*(*studentdata).kasse0_blockiert)=(*studentdata).id;
    
                //Überprüfen ob zwischenzeitlich ein anderer Student die Sperrvariable
                //gesetzt hat
                if((*(*studentdata).kasse0_blockiert)==(*studentdata).id)
                {
                    //Nächsten Studenten an den Anfang der Warteschlange bewegen
                    (*(*studentdata).wskasse).first=(*studentdata).next;
    
                    printf("Student Nr. %d steht an Kasse Nr. 0 und bezahlt.\n",(*studentdata).id);
    
                    //Student braucht mal wieder ewig um seinen Ausweis zu finden, weil er
                    //vorher die ganze Zeit an dicke Titten gedacht hat, anstatt mal
                    //rechtzeitig seinen Ausweis rauszusuchen
                    sleep((*studentdata).wartezeit_kasse);
    
                    //Student bezahlt
                    (*(*studentdata).kasse0)=(*(*studentdata).kasse0)+1;
    
                    printf("Student Nr. %d verlässt jetzt Kasse Nr. 0.\n",(*studentdata).id);
    
                    //Rücksetzen der Sperrvariablen
                    (*(*studentdata).kasse0_blockiert)=0xFFFFFFFF;
                    break;
                }
            }
    
            //Überprüfen ob bereits ein Student an Kasse 1 bezahlt bzw. ob die
            //Sperrvariable für kasse1 gesetzt ist.
            if((*(*studentdata).kasse1_blockiert)==0xFFFFFFFF)
            {
                //Setzen der Sperrvariable für Kasse 1
                (*(*studentdata).kasse1_blockiert)=(*studentdata).id;
    
                //Überprüfen ob zwischenzeitlich ein anderer Student die Sperrvariable
                //gesetzt hat
                if((*(*studentdata).kasse1_blockiert)==(*studentdata).id)
                {
                    //Nächsten Studenten an den Anfang der Warteschlange bewegen
                    (*(*studentdata).wskasse).first=(*studentdata).next;
    
                    printf("Student Nr. %d steht an Kasse Nr. 1 und bezahlt.\n",(*studentdata).id);
    
                    //Student braucht mal wieder ewig um seinen Ausweis zu finden, weil er
                    //vorher die ganze Zeit an dicke Titten gedacht hat, anstatt mal
                    //rechtzeitig seinen Ausweis rauszusuchen
                    sleep((*studentdata).wartezeit_kasse);
    
                    //Student bezahlt
                    (*(*studentdata).kasse1)=(*(*studentdata).kasse1)+1;
    
                    printf("Student Nr. %d verlässt jetzt Kasse Nr. 1.\n",(*studentdata).id);
    
                    //Rücksetzen der Sperrvariablen
                    (*(*studentdata).kasse1_blockiert)=0xFFFFFFFF;
                    break;
                }
            }
    
            //Überprüfen ob bereits ein Student an Kasse 2 bezahlt bzw. ob die
            //Sperrvariable für kasse2 gesetzt ist.
            if((*(*studentdata).kasse2_blockiert)==0xFFFFFFFF)
            {
                //Setzen der Sperrvariable für Kasse 2
                (*(*studentdata).kasse2_blockiert)=(*studentdata).id;
    
                //Überprüfen ob zwischenzeitlich ein anderer Student die Sperrvariable
                //gesetzt hat
                if((*(*studentdata).kasse2_blockiert)==(*studentdata).id)
                {
                    //Nächsten Studenten an den Anfang der Warteschlange bewegen
                    (*(*studentdata).wskasse).first=(*studentdata).next;
    
                    printf("Student Nr. %d steht an Kasse Nr. 2 und bezahlt.\n",(*studentdata).id);
    
                    //Student braucht mal wieder ewig um seinen Ausweis zu finden, weil er
                    //vorher die ganze Zeit an dicke Titten gedacht hat, anstatt mal
                    //rechtzeitig seinen Ausweis rauszusuchen
                    sleep((*studentdata).wartezeit_kasse);
    
                    //Student bezahlt
                    (*(*studentdata).kasse2)=(*(*studentdata).kasse2)+1;
    
                    printf("Student Nr. %d verlässt jetzt Kasse Nr. 2.\n",(*studentdata).id);
    
                    //Rücksetzen der Sperrvariablen
                    (*(*studentdata).kasse2_blockiert)=0xFFFFFFFF;
                    break;
                }
            }
    
            //Überprüfen ob bereits ein Student an Kasse 3 bezahlt bzw. ob die
            //Sperrvariable für kasse0 gesetzt ist.
            if((*(*studentdata).kasse3_blockiert)==0xFFFFFFFF)
            {
                //Setzen der Sperrvariable für Kasse 3
                (*(*studentdata).kasse3_blockiert)=(*studentdata).id;
    
                //Überprüfen ob zwischenzeitlich ein anderer Student die Sperrvariable
                //gesetzt hat
                if((*(*studentdata).kasse3_blockiert)==(*studentdata).id)
                {
                    //Nächsten Studenten an den Anfang der Warteschlange bewegen
                    (*(*studentdata).wskasse).first=(*studentdata).next;
    
                    printf("Student Nr. %d steht an Kasse Nr. 3 und bezahlt.\n",(*studentdata).id);
    
                    //Student braucht mal wieder ewig um seinen Ausweis zu finden, weil er
                    //vorher die ganze Zeit an dicke Titten gedacht hat, anstatt mal
                    //rechtzeitig seinen Ausweis rauszusuchen
                    sleep((*studentdata).wartezeit_kasse);
    
                    //Student bezahlt
                    (*(*studentdata).kasse3)=(*(*studentdata).kasse3)+1;
    
                    printf("Student Nr. %d verlässt jetzt Kasse Nr. 3.\n",(*studentdata).id);
    
                    //Rücksetzen der Sperrvariablen
                    (*(*studentdata).kasse3_blockiert)=0xFFFFFFFF;
                    break;
                }
            }
    
            usleep(1000);
        }
    
        free(studentdata);
        pthread_exit(NULL);
    }
    


  • HansKlaus schrieb:

    syntactic sugar schrieb:

    (*pointer_auf_struct).element == pointer_auf_struct->element

    Das weiß ich. Aber pointer_auf_struct->(pointer_in_struct) geht z.b. nicht,
    (
    (*pointer_auf_struct).pointer_in_struct) dagegen schon.

    Das Erste ist ja auch Unfug.

    weiß eigentlich jemand, wie ich Dinge wie pointer_auf_struct->array_in_struct[3] nur unter Verwendung von Dereferenzierungs-Operatoren mache? Also irgendwas im Sinne von (*(*struktur).(zeiger+3))?

    C hat klare Regeln, die muss man befolgen und dann funktioniert auch alles. Ich habe das Gefühl du rätst mehr.

    Das hier beantwortet die Fragen hoffentlich.

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct
    {
    	int a;
    	int b;
    	int arr[7];
    	int *ptrintern;
    } test_t;
    
    int main(void)
    {
    	test_t * ptr;
    
    	int z=42;
    
    	ptr=malloc(sizeof(test_t));
    	if(ptr==NULL) { printf("waaaah"); return 1; }
    
    	ptr->a=1;
    	ptr->b=2;
    
    	ptr->arr[0]=10;
    	ptr->arr[1]=11;
    	ptr->arr[2]=12;
    
    	ptr->ptrintern=&z;
    	(*(ptr->ptrintern))++;
    
    	printf("%d  %d   %d   %d   %d   %d\n", (*ptr).a, (*ptr).b, *((*ptr).arr+0), *((*ptr).arr+1), *((*ptr).arr+2), *((*ptr).ptrintern));
    
    	return 0;
    }
    

    Es mag Klammern geben die man sich sparen kann, aber lieber eine mehr, ich muss zugeben die Operatorenreihenfolge habe ich nicht im Kopf.

    BTW, in deinem Code: void *StudentProc(struct StudentData *studentdata) hat entweder (wahrscheinlich) einen Stern zu viel oder du hast den Rückgabewert vergessen. Und persönlich - aber ich bin kein Profi - finde ich diese for( ;; )+break ziemlich ekelig.



  • Habs hinbekommen, danke!

    dass *((*struktur).zeiger) richtig ist, ist irgendwie ja auch einleuchtend, nur in meinem buch standen derartige Sachen nicht so direkt drin und ich kam irgendwie nicht drauf. Ist eben nicht so einfach, aber jetzt weiß ichs ja. 😃



  • Und noch kürzer (und prägnanter) geht es mittels

    *struktur->zeiger
    

    -> bindet stärker als *
    Entspricht also

    *(struktur->zeiger)
    

Anmelden zum Antworten