Dynamische Datenstrukturen



  • Siemens hat zwar zweifellos Bugs, aber in diesem Fall sicher nicht.
    Der Compiler hat immer Recht.
    Wir sind hier ein C Forum, in dem es somit um Fragestellungen der Sprache C, vorzugsweise von Standard C geht und nicht um irgendwelche, nicht reproduzierbaren lokalen Compiler/IDE Konfigurationen.
    Schreibe mal eine konkrete Variante deines nicht funktionierenden Codes auf, alles zusammen in einer Datei (d.h. ohne Header und Kommentare), wenn es nicht zuviel wird.



  • OK ich merke schon das wir hier nicht weiterkommen werden.
    KP was du von mir möchtest. Oben stehen die einzelnen Funktionen die auch so wie oben abgebildet jeweils eine eigene Datei hat. Mit Außnahme von dem Button. Weil das ist in einer Visualisierung.

    Zum Thema der "Compiler hat immer Recht" sag ich nur der Compiler ist so dumm wie 5 Meter Feldweg. Weil ich schon eine Variante hatte indem das compilieren nicht zuende ging und ich nur noch den Task beenden konnte.

    Vielen Dank



  • Ich schiebe es mal auf deine mangelnde Erfahrung im Umgang mit C Compilern.
    Du bist hier nicht der erste, der meint, sein Code sei korrekt und der Compiler Schrott. Bisher hat hier aber noch niemand dann auch konkret diesen angeblichen Compilerfehler nachgewiesen.
    Wenn du nicht in der Lage bist, hier reproduzierbare konkrete Quellcodes zu schreiben, kann dir auch niemand vernünftig helfen.
    Aussagen wie "wenn ich es so mache, funktioniert es nicht..." sind suboptimal für eine Problemlösung, wobei es bei deinem Problem "unresolved reference..." auch eher nach einem Linker-Problem aussieht, d.h. du hast dich ganz einfach bei deinen (anspruchsvollen) Funktionsnamen verschrieben.



  • Hallo Wutz,

    ich habe in meine oberen Code die Kommentare und die Header rausgenommen und hoffe das dies somit schon mal besser ist.

    Deine Idee mit über das Thema unresolved reference... ist soweit Normalerweise auch richtig. Leider ist es folgendermaßen:

    Wie oben zu sehen habe ich die Funktion IPKQKDynListStringAusgabe, hier hat der Compiler wohl auch sein Problem. Wie man in der Fehlermeldung sehen kann.

    'IPKQKDynListStringAusgabe': unresolved external function

    Da ich ja wuste, OK da ist irgendwie das Problem habe ich die Schreibweisen geprüft. UND kein Problem gefunden.
    Nach probieren und probieren sah meine Funktion irgendwann einmal so aus:

    #include "apdefap.h"
    #include "IPKQKDynListString.h"
    
    BOOL IPKQKDynListStringAusgabe()
    {
    
     return 0 ;
    }
    

    Gut den Aufruf musste ich natürlich auch anpassen, da ich keine Parameter mehr hatte.

    OK danach hatte ich folgende Meldung:

    'IPKQKDynListStringAusgabe': unresolved external function

    OK das Problem ist also immer noch da.

    Gut was haben wir dann noch 😕 genau den Header, mache also folgendes:

    #include "apdefap.h"
    
    BOOL IPKQKDynListStringAusgabe()
    {
    
     return 0 ;
    }
    

    nun versuche ich es erneut.

    Super die Funktion IPKQKDynListStringAnhaengen wird immernoch ohne Fehler abgearbeitet UND die Funktion IPKQKDynListStringAusgabe hat keine Fehler mehr.

    Ich habe noch ein printf("Test\r\n"); hinzugefügt um zu schauen ob die Funktion aufgerufen wird. OK alles Fehlerfrei.

    nun habe ich den HEADER IPKQKDynListString.h (den ich auch schon in dem Button und in der Funktion IPKQKDynListStringAnhaengen angegeben habe wieder via COPY und Paste hinzugefügt UND die schreibweise überprüft. und siehe da:

    'IPKQKDynListStringAusgabe': unresolved external function
    ====================================OnErrorExecute====================================
    SystemTime: (ThreadId 10032) 2011-03-25 07:45:53.843
    dwErrorCode1: (ThreadId 10032) 1007001
    dwErrorCode2: (ThreadId 10032) 4099
    szErrorText: (ThreadId 10032) Exception in Action
    szErrorTextException: (ThreadId 10032) unresolved external function or variable
    szApplicationName: (ThreadId 10032) PDLRuntimeSystem
    bCycle: (ThreadId 10032) acycle
    szFunctionName: (ThreadId 10032) @132
    lpszPictureName: (ThreadId 10032) @SCREEN.@WIN12:@1001.@DESK:TESTGUID
    lpszObjectName: (ThreadId 10032) Button3
    lpszPropertyName: (ThreadId 10032) (NULL)
    dwParamSize: (ThreadId 10032) 12
    ====================================OnErrorExecute====================================

    Also entweder bin ich so doof wie 10 Meter Feldweg ODER der Compiler hat nen Problem.

    😕

    Was meinst du Wutz?



  • Ich habe noch etwas versucht:

    Folgendes: Ich habe nun den Inhalt aus der Ausgabe Funktion in die IPKQKDynListStringAnhaengen eingebaut.
    Die Ausgabe funktioniert dann auch. (Funktionsaufruf von IPKQKDynListStringAusgabe auskommentiert)

    [cpp].
    .
    .
    }
    zeiger=zeiger->next;
    strcpy(zeiger->dynListString,value);
    zeiger->next=NULL;
    printf("In Liste Hinzugefügt\r\n");
    }

    while(zeiger != NULL) {
    printf("Stringwert: %s\r\n",
    zeiger->dynListString);
    zeiger=zeiger->next;
    }

    return returnValue;
    } [/cpp]

    nun habe ich den Inhalt wieder rausgenommen und den Funktionsaufruf für IPKQKDynListStringAusgabe wieder hinzugefügt.

    Jetzt ist es so das ich die Fehlermeldung bei IPKQKDynListStringAnhaengen habe.

    Wenn die Funktion nun auskommentere IPKQKDynListStringAnhaengen ODER die Funktion IPKQKDynListStringAusgabe davor setzte dann Funktioniert die funktion IPKQKDynListStringAusgabe.

    Allerdings bekomm Funktioniert IPKQKDynListStringAnhaengen garnicht mehr.

    Alles jetzt umgekehrt.

    Mach ich beim Aufruf etwas falsch ? so das ich irgendwo in ein Speicherproblem laufen könnte oder was ist das?



  • Hast Du alle includes die Du brauchst richtig geschrieben? und werden diese gefunden?



  • Also es gibt 2 Datein die über ein Button HEADER generieren erzeugt werden (man kann die Datein auch löschen und diese werden dann neu erstellt)

    Einmal APDEFAP.H in der nur auf AP_PBIB.H gelinkt wird.
    Dann gibt es die AP_PBIB.H in der meine Header eingetragen wurden.

    .
    .
    .
    BOOL IPKQKDynListStringAnhaengen (char* value, struct IPKQKDynListString* zeiger);	//GSC_NAME:IPKQKDynListStringAnhaengen	GSC_PROTOTYPE:\ipkqk\ipkqkdynliststringanhaengen.fct
    BOOL IPKQKDynListStringAusgabe (struct IPKQKDynListString* zeiger);	//GSC_NAME:IPKQKDynListStringAusgabe	GSC_PROTOTYPE:\ipkqk\ipkqkdynliststringausgabe.fct
    .
    .
    .
    

    Also da hab ich die Tage auch kein Problem gesehen.

    Also man muss auch dazusagen das diese Fehlermeldung nichtssagend ist. Ich hatte diese auch schon als ich ein printf gemacht hatte und ich glaube als wert einen String hatte aber als ausgabe %d gemacht habe.

    Das ist glaube ich sowas wie eine Standartfehlermeldung bei dem SIEMENS Compiler 😡

    Was sagst du zum aufruf der Funktion bei meinen oben beschriebenen Beispiel?

    Siehst du dort ein kritisches Problem? oder würdest du sagen neeee so geht das nicht?

    Weil die Funktionen ansich Funktionieren ja nur das ich es nicht getrent hinbekomme.

    Vielleicht zerhaue ich...... ach ich hab keine Idee oder Ahnung mehr .... so langsam frustet es einen. 😞



  • Übrigens wenn jeman es Testen würde oder möchte.

    Das Beispiel im ersten Eintrag ist alles was benötigt wird bzw. was ich dazu verwende.

    Es sollte immer der gleiche Text in die Liste geschrieben werden und es wird immer die ganze Liste wieder ausgegeben. (also zumindest in der Theorie).



  • Also ich glaube langsam wirklich das es irgendwo ein Speicherproblem ist, weil ich habe jetzt die VM Heruntergefahren und gestartet und jetzt geht die Funktion IPKQKDynListStringAnhaengen wieder.

    Aber dafür IPKQKDynListStringAusgabe nicht. Da bekomme ich jetzt wieder die Fehlermeldung 'IPKQKDynListStringAusgabe': unresolved external function

    Kann jemand mal bitte das am Anfang beschriebene Programm testen? So langsam verzweifel ich. Vielen Dank



  • Also ich habe nun mal folgendes gemacht:

    Ich habe das beispiel von Galileo Computing genommen und den Dev-C++ Compiler

    Das beispiel funktioniert.

    Nun habe ich es etwas abgespeckt und den Header in eine eigene Datei gelegt. (um langsam an mein Beispiel herran zu kommen.)

    Header (Dateiname: angestellt.h)

    struct angestellt{
       char name[MAX];
       struct angestellt *next;
    };
    
    struct angestellt *next   = NULL;
    struct angestellt *anfang = NULL;
    

    Main: (Dateiname: main.c)

    /* linear_list2.c */
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <angestellt.h>
    #define MAX 20
    
    void anhaengen(char *n) {
       struct angestellt *zeiger;
    
       if(anfang == NULL) {
    
          if((anfang =
           malloc(sizeof(struct angestellt))) == NULL) {
             fprintf(stderr, "Kein Speicherplatz vorhanden "
                             "für anfang\n");
             return;
          }
          strcpy(anfang->name, n);
    
          anfang->next=NULL;
       }
    
       else {
          zeiger=anfang; 
          while(zeiger->next != NULL)
             zeiger=zeiger->next;
    
          if((zeiger->next =
           malloc(sizeof(struct angestellt))) == NULL) {
              fprintf(stderr,"Kein Speicherplatz für das "
                             "letzte Element\n");
              return;
          }
          zeiger=zeiger->next; 
          strcpy(zeiger->name,n);
          zeiger->next=NULL;
       }
    }
    
    /* Funktion zum Ausgeben der Dateien */
    void ausgabe(void) {
       struct angestellt *zeiger = anfang;
    
       while(zeiger != NULL) {
          printf("%12s\n",
             zeiger->name);
             zeiger=zeiger->next;
       }
    }
    
    int main(void) {
       int wahl;
       char dname[MAX];
    
       do {
          printf("\n1 : Eingabe\n");
          printf("2 : Ausgabe\n");
          printf("9 : Ende\n");
          printf("Ihre Wahl : ");
          scanf("%d",&wahl);
          getchar();
          switch(wahl) {
             case 1 : anhaengen("TestX");
                      break;
             case 2 : ausgabe();
                      break;
             case 9 : break;
             default: printf("Falsche Eingabe!!!\n");
          }
       } while(wahl != 9);
       return EXIT_SUCCESS;
    }
    

    Soweit so gut alles Funktioniert:

    nun wollte ich die Funktion anhaengen in eine eigene Datei legen:

    Also:

    Main Datei (Dateiname main.c)

    /* linear_list2.c */
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <angestellt.h>
    #define MAX 20
    
    /* Funktion zum Ausgeben der Dateien */
    void ausgabe(void) {
       struct angestellt *zeiger = anfang;
    
       while(zeiger != NULL) {
          printf("%12s\n",
             zeiger->name);
             zeiger=zeiger->next;
       }
    }
    
    int main(void) {
       int wahl;
       char dname[MAX];
    
       do {
          printf("\n1 : Eingabe\n");
          printf("2 : Ausgabe\n");
          printf("9 : Ende\n");
          printf("Ihre Wahl : ");
          scanf("%d",&wahl);
          getchar();
          switch(wahl) {
             case 1 : anhaengen("TestX");
                      break;
             case 2 : ausgabe();
                      break;
             case 9 : break;
             default: printf("Falsche Eingabe!!!\n");
          }
       } while(wahl != 9);
       return EXIT_SUCCESS;
    }
    

    und Funktion Anhängen (Dateiname: anhaengen.c)

    /* linear_list2.c */
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <angestellt.h>
    #define MAX 20
    
    void anhaengen(char *n) {
       struct angestellt *zeiger;
    
       if(anfang == NULL) {
    
          if((anfang =
           malloc(sizeof(struct angestellt))) == NULL) {
             fprintf(stderr, "Kein Speicherplatz vorhanden "
                             "für anfang\n");
             return;
          }
          strcpy(anfang->name, n);
    
          anfang->next=NULL;
       }
    
       else {
          zeiger=anfang; 
          while(zeiger->next != NULL)
             zeiger=zeiger->next;
    
          if((zeiger->next =
           malloc(sizeof(struct angestellt))) == NULL) {
              fprintf(stderr,"Kein Speicherplatz für das "
                             "letzte Element\n");
              return;
          }
          zeiger=zeiger->next; 
          strcpy(zeiger->name,n);
          zeiger->next=NULL;
       }
    }
    

    nun wollte ich es compilieren aber bekomme folgende Fehlermeldung:

    multiple definition of next' first defined here multiple definition ofanfang'
    first defined here
    ld returned 1 exit status
    C:\Dev-Cpp\Projekt Denis\Makefile.win [Build Error] [Projekt1.exe] Error 1

    Was muss ich machen damit ich diese Meldung nicht mehr bekomme bzw. wie würde der Lösungsweg aussehen?

    vielleicht ist dies mein Problem was ich auch beim SIEMENS Compiler habe aber er es nicht richtig anzeigt...

    Vielen lieben Dank an euch schon mal
    MfG



  • Der Compiler (in diesem Fall sogar der Linker) hat wie immer Recht.
    Du inkludierst die Definition von next+anfang 2 mal durch 2 maliges Inkludieren von <angestellt.h>, was üblicherweise "angestellt.h" heissen sollte.
    Ich kann immer noch keinen Compilerfehler entdecken.



  • Mit

    struct angestellt *next   = NULL;
    struct angestellt *anfang = NULL;
    

    legst du die Variablen (Zeiger) next und anfang an.

    Das passiert jedesmal wenn die Datei includiert wird.

    Schreib das einfach an den Anfang der Datei mit main. Nach den #include und #define.



  • Also Danke schon mal an DirkB das werde ich gleich einmal außprobieren, aber erst noch einmal zu Wutz:

    Was ist der Unterschied zwischen <> und ""

    und wie soll ich das jetzt nach deiner Meinung machen, damit ich das nicht doppelt Includiere?

    Weil ich hätte das schon gerne im Header, außer das ist nicht möglich dann mach ich es halt wie DirkB es beschreibt.



  • <> sucht die includes im Compilerpfad.
    "" sucht auch im aktuellen Verzeichnis (da wo die C-Datei steht).

    Variablendeklarationen haben in Headerdateien nichts zu suchen.



  • Falsch.
    Deklarationen gehören genau in Headerdateien.
    Definitionen gehören da nicht hin.



  • Ich habe das beispiel von Galileo Computing genommen und den Dev-C++ Compiler

    2 Fehler auf einmal, Gratulation 👍
    Sind die Initialen des Autors zufälligerweise J.W.? 🤡


  • Mod

    314159265358979 schrieb:

    Sind die Initialen des Autors zufälligerweise J.W.? 🤡

    Ja, sind sie, wie man am Link im ersten Beitrag sieht.



  • Ah, stimmt, danke. 😃



  • Also entweder stelle ich mich zu blöde an oder ich versteh das nicht richtig.

    ich habe jetzt

    struct angestellt *next = NULL; UND
    struct angestellt *anfang = NULL;

    aus den Header genommen und in der main Funktion eingefügt

    main.c

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "angestellt.h"
    #define MAX 20
    
    struct angestellt *next   = NULL;
    struct angestellt *anfang = NULL;
    
    /* Funktion zum Ausgeben der Dateien */
    void ausgabe(void) {
       struct angestellt *zeiger = anfang;
    
       while(zeiger != NULL) {
          printf("%12s\n",
             zeiger->name);
             zeiger=zeiger->next;
       }
    }
    
    int main(void) {
       int wahl;
       char dname[MAX];
    
       do {
          printf("\n1 : Eingabe\n");
          printf("2 : Ausgabe\n");
          printf("9 : Ende\n");
          printf("Ihre Wahl : ");
          scanf("%d",&wahl);
          getchar();
          switch(wahl) {
             case 1 : anhaengen("TestX");
                      break;
             case 2 : ausgabe();
                      break;
             case 9 : break;
             default: printf("Falsche Eingabe!!!\n");
          }
       } while(wahl != 9);
       return EXIT_SUCCESS;
    }
    

    jetzt würde ich davon ausgehen das alles richtig ist oder?

    Warum bekomme ich immernoch den Fehler?

    multiple definition of next' first defined here multiple definition ofanfang'
    first defined here
    ld returned 1 exit status



  • So jetzt hab ich glaube ich verstanden was Ihr meint.

    Moment Post kommt gleich.


Anmelden zum Antworten