Dynamische Datenstrukturen



  • Hi,

    also ich versuche gerade in Ansi-C (unter WinCC) eine Dynamische Datenstruktur zu erzeugen. Leider bekomme ich immer Fehler egal was ich versuche.

    Wie die Dynamischen Datenstruckturen funktionieren hab ich mir hier abgeschaut:

    http://openbook.galileocomputing.de/c_von_a_bis_z/021_c_dyn_datenstrukturen_001.htm#mj7c56df0693563276c6713057fe39a2ef

    Hier die Skripte:

    Header Datei:

    struct IPKQKDynListString{
    	char dynListString[255];
    	struct IPKQKDynListString *next;
    };
    
    struct IPKQKDynListString *next   = NULL;
    struct IPKQKDynListString *anfang = NULL;
    

    Aufruf aus einem Button:

    #include "apdefap.h"
    void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
    {
    #include "IPKQKDynListString.h"
    
       struct IPKQKDynListString *zeiger;
       IPKQKDynListStringAnhaengen("WERTx", zeiger);
       IPKQKDynListStringAusgabe(anfang);}
    

    Nun die Funktion IPKQKDynListStringAnhaengen:

    #include "apdefap.h"
    #include "IPKQKDynListString.h"
    
    BOOL IPKQKDynListStringAnhaengen(char *value,struct IPKQKDynListString *zeiger)
    {
    BOOL returnValue = EXIT_SUCCESS;
       if(anfang == NULL) {
          if((anfang =
           malloc(sizeof(struct IPKQKDynListString))) == NULL) {
             fprintf(stderr, "Kein Speicherplatz vorhanden "
                             "für anfang\n");
             returnValue = EXIT_FAILURE;
          }
          strcpy(anfang->dynListString, value);
          anfang->next=NULL;
    	printf("Anfang der Liste\r\n");
       }
       else {
          zeiger=anfang;
          while(zeiger->next != NULL)
             zeiger=zeiger->next;
          if((zeiger->next =
           malloc(sizeof(struct IPKQKDynListString))) == NULL) {
              fprintf(stderr,"Kein Speicherplatz für das "
                             "letzte Element\n");
              returnValue = EXIT_FAILURE;
          }
          zeiger=zeiger->next;
          strcpy(zeiger->dynListString,value);
          zeiger->next=NULL;
    	printf("In Liste Hinzugefügt\r\n");
       }
    return returnValue;
    }
    

    und nun die Funktion IPKQKDynListStringAusgabe

    #include "apdefap.h"
    #include "IPKQKDynListString.h"
    
    BOOL IPKQKDynListStringAusgabe(struct IPKQKDynListString *zeiger)
    {
    
    BOOL returnValue = EXIT_SUCCESS;	
       while(zeiger != NULL) {
          printf("Stringwert: %s\r\n",
             zeiger->dynListString);
             zeiger=zeiger->next;
       }
    
     return returnValue ;
    }
    

    Das Ergebnis ist immer ein Fehler:
    '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====================================

    oder wenn ich es irgendwie anders baue bekomme ich immer eine Meldung das
    anfang und next doppelt verwendet wird.

    Die Funktion IPKQKDynListStringAnhaengen Funktioniert immer. Aber eien 2. Funktion die mit dem Header zu tun hat bringt mir dann immer die obere Fehlermeldung. (Die Funktion 'IPKQKDynListStringAusgabe' kann leer sein solange das #include "IPKQKDynListString.h" drinne ist bekomme ich immer den Fehler.

    Ich habe auch schon versucht 2 IPKQKDynListStringAnhaengen Funktionen zu machen (Copy Paste) also:

    IPKQKDynListStringAnhaengen
    IPKQKDynListStringAnhaengenB

    ich bekomme es erst zum laufen wenn ich 2 Headerdatein habe wo auch anfang und next umbenannt sind (anfangB und nextB)

    erst dann funktioniert auch IPKQKDynListStringAnhaengenB.

    Nun noch mal zurück zum Hauptproblem warum funktioniert das mit 'IPKQKDynListStringAusgabe' nicht?

    Wie muss ich die Aufrufe richtig machen? Ich hab schon einiges versucht aber nix geht.



  • LHBL2003 schrieb:

    oder wenn ich es irgendwie anders baue bekomme ich immer eine Meldung das
    anfang und next doppelt verwendet wird.

    Ohne Worte.
    Jetzt geht der JW Müll schon wieder los.
    Baue mal eine fehlerfrei compilierbare Version zusammen und stelle dann eine konkrete Frage.



  • Hallo Wutz,

    wenn ich eine fehlerfrei compilierbare Version hinbekommen würde, müsste ich keinen Beitrag hier schreiben.

    Ich verstehe nicht warum ich dieses Problem habe. Bzw ich weiß nicht was ich anders machen muss damit es Funktioniert.

    😕

    So langsam glaube ich daran das es bei SIEMENS ein BUG ist. Weil ich schon zich Versionen probiert habe, aber nix funktionsfähiges hinbekommen.

    Weil je nach Testversuch schaffe ich es auch, dass ich nicht zuende compilieren kann.

    Würde mich freuen wenn du das durch dein C-Compiler jagen könntest, vielleicht hast du keine Probleme.



  • 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.


Anmelden zum Antworten