compilerfehler oder falsche bezeichner (war: ADT...)



  • Folgende Datei...

    /* assotable.c */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "assotable.h"
    
    int hash(char *str, int table_size) 
    {
     int sum, i; 
     if (str==NULL) return -1; 
     for(i=0; str[i]; i++) sum += str[i]; 
     return sum % table_size;
    }
    
    struct Entry 
    {
     char *key;
     void *info;
     int len;
     Entry *next;
    };
    
    struct AssoTab_T 
    {
     Entry table[LENGTH]; 
    };
    
    AssoTab new_AssoTab() 
    { 	 
     return (AssoTab) calloc(sizeof(struct AssoTab_T),1); 	 
    } 	 
    
    void free_AssoTab(AssoTab *tab_p) 
    { 	 
     int i;
     if (!(tab_p && *tab_p)) return; // do nothing 	 
     for (i=0; i<LENGTH; i++) free_Entry_list(*tab_p->table[i]); 	 
     free(*tab_p); 	 
     *tab_p = NULL; 	 
    } 	 
    
    static void free_Entry_list(Entry en) 
    { 	 
     if (en) 
     { 	 
      free_Entry-list(en->next); 	 
      free(en); 	 
     } 	 
    }
    
    42: request for member `table' in something not a structure or union
    

    Der fehler tritt in free_AssoTab an der Stelle wo "table" steht auf!

    Hier noch die header...

    /* assotable.h */
    
    #ifndef LENGTH
    #define LENGTH 15
    #endif
    
    typedef struct Assotab *AssoTab;
    
    typedef struct Entry *Entry;
    
    AssoTab new_AssoTab();
    
    void free_AssoTab(AssoTab *tab);
    
    static void free_Entry_list(Entry en);
    
    int hash(char *str, int table_size); 
    
    int enter_AssoTab(AssoTab tab, char *key, void *info, int length); // returns -1 if key contained
    
    int remove_AssoTab(AssoTab tab, char *key);        // returns 0 if key not contained
    
    int read_AssoTab(AssoTab tab, char *key, void ** result, int *length);  // returns 0 if key not contained
    

    Danke für etwaige Hilfe...

    Edit by c.rackwitz: deine ueberschrift laesst zu wuenschen uebrig. habe sie etwas ausgeschmueckt.



  • Wieso guckst du dir nicht die Zeilen an, die fehlerhaft sind? Dann würdest du sehen, dass bei dir in "struct AssoTab_T" anstatt "Entry table[LENGTH];" "struct Entry table[LENGTH];" stehen muss. Genauso ist das bei "AssoTab new_AssoTab() " und ein paar anderen.



  • ma davon abgesehen, dass ich C net wirklich durchschaue....

    habs probiert, geht nicht, hast du auch die assotab.h gesichtet

    dort steht

    typedef struct Assotab *AssoTab;
    
    typedef struct Entry *Entry;
    

    das sollte doch genau das machen oder???

    gruß



  • Ah, nicht gesehen, aber das Problem ist dann:

    typedef struct Assotab *AssoTab;

    Der ist ok, weil es sich in Groß- und Kleinschreibung unterscheidet

    typedef struct Entry *Entry;

    aber ist gleich. Mach mal

    typedef struct Entry *Entry_t;

    und ändere Entry in den entsprechenden Zeilen um auf Entry_t



  • genau so gemacht,

    typedef struct Entry *Entry_T;

    alle "Entry" dann zu "Entry_T" geändert problem: das gleiche 🙂 😞



  • hab statt großklein-schreibung nun mal mit anderen bezeichnern angepasst...

    hier diese Version is aktuell:

    header:

    /* assotable.h */
    
    #ifndef LENGTH
    #define LENGTH 15
    #endif
    
    typedef struct AssoTab *AssoTab_T;
    
    typedef struct Entry *Entry_T;
    
    AssoTab_T new_AssoTab();
    
    void free_AssoTab(AssoTab_T *tab);
    
    static void free_Entry_list(Entry_T *en);
    
    int hash(char *str, int table_size); 
    
    int enter_AssoTab(AssoTab_T tab, char *key, void *info, int length); // returns -1 if key contained
    
    int remove_AssoTab(AssoTab_T tab, char *key);        // returns 0 if key not contained
    
    int read_AssoTab(AssoTab_T tab, char *key, void ** result, int *length);  // returns 0 if key not contained
    

    source

    /* assotable.c */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "assotable.h"
    
    int hash(char *str, int table_size) 
    {
     int sum, i; 
     if (str==NULL) return -1; 
     for(i=0; str[i]; i++) sum += str[i]; 
     return sum % table_size;
    }
    
    struct Entry 
    {
     char *key;
     void *info;
     int len;
     Entry_T *next;
    };
    
    struct AssoTab 
    {
     Entry_T table[LENGTH]; 
    };
    
    AssoTab_T new_AssoTab() 
    { 	 
     return (AssoTab_T) calloc(sizeof(struct AssoTab),1); 	 
    } 	 
    
    void free_AssoTab(AssoTab_T *tab_p) 
    { 
     int i;
     if (!(tab_p && *tab_p)) return; // do nothing 	 
     for (i=0; i<LENGTH; i++) free_Entry_list(*tab_p->table[i]); 	 
     free(*tab_p); 	 
     *tab_p = NULL; 	 
    } 	 
    
    static void free_Entry_list(Entry_T *en) 
    { 	 
     if(en) 
     { 	 
      free_Entry_list(en->next); 	 
      free(en); 	 
     } 	 
    }
    


  • for (i=0; i<LENGTH; i++) free_Entry_list(*tab_p->table[i]);
    

    der dereferenzierungs-operator bindet schwächer als -> und []. du mußt deshalb klammern setzten:

    for (i=0; i<LENGTH; i++) free_Entry_list((*tab_p)->table[i]);
    


  • EDIT: ok das wars erstma der fehler

    hm nun erhalte ich folgende fehlermeldung, kompiliert aber...

    42 D:\Studium\PRG2\x6\assotable.c [Warning] passing arg 1 of `free_Entry_list' from incompatible pointer type
    

    ich hoffe es geht dann auch, mit zeigern steh ich nämlich auf kriegsfuss... die ironie is das ich grad die note meiner c-programmiern klausur erfahren hab 😃 🙄 naja



  • Dein code ist furchtbar zu lesen.
    erstmal würde ich dir raten die typedefs loszuwerden oder sie zumindest folgendermassen zu ändern

    typedef struct AssoTab AssoTab_T;
    typedef struct Entry Entry_T;
    

    So wie du sie jetzt hast ist es ja fast unmöglich herauszufinden was jetzt ein pointer oder ein pointer auf einen pointer oder gar die struct selbst ist.
    Dann solltest du die structs auch im header definieren. Mit deinen typedefs funktioniert es zwar solange du nur ein .c -file hast. Wenn du den header aber in mehreren .c-files verwenden willst bekommst du wahrscheinlich linker-fehler.
    Nur ein paar Anregungen
    Kurt



  • Hi Kurt,

    das Problem ist, dass ich :

    1. (noch) net so viel Ahnung von der Materie hab
    2. diese Struktur vom Prof vorgegebn wurde...

    tja so is das...

    bzgl struct im header definieren...

    da wurde uns das so gelehrt, dass bei Abstrakten DatenTyp die Struktur NICHT im Header auftaucht...

    daher auch so die Vorgabe.. denk ich ma :D, ich will mich da jetzt nur noch durchwurschteln.. 😉



  • Na ja mit Abstrakten DatenTypen kenn ich mich nicht aus.
    Dein Problem kommt aber wahrscheinlich daher dass du scheinbar den Parametertyp von free_Entry_list() zwischen 1. und letztem Posting geändert hast
    Im 1. Posting

    static void free_Entry_list(Entry en);
    

    Da wer vermutlich Entry als pointer auf struct Entry gemeint was IMHO Sinn macht.
    Jetzt ist es so definiert

    static void free_Entry_list(Entry_T *en);
    

    en ist jetzt ein Pointer auf einen Pointer auf struct Entry. Im Code deutet alles darauf hin dass du struct Entry's freigeben willst nicht pointer darauf.
    BTW : static in dieser function macht das ganze wahrscheinlich abstrakt 😉
    Kurt



  • diese ganzen Funktionen sind in Folien zugefasst vom Prof, leider auch mit vielen Fehlern drin...
    habe jetzt das Modul fast fertig tauchen 3-4 Warnungen bzgl Pointer auf (um die ich mich erstmal nich kümmer...

    folgende letzen beiden Funktionen bereiten mir Schwierigkeiten...

    int remove_AssoTab(AssoTab_T tab, char *key)
    {
     int index = hashfunction(key, LENGTH);
     if (tab->table[index] == 0) return 0; // no entry
     else 
     {
      Entry_T en = find_pred(tab->table[index], key);
      if (!en->next) return 0; // not in list
      Entry_T rem = &(en->next);
      en->next = en->next->next; // remove
      free_Entry(rem);
      return 1;
     }
    }
    
    static Entry_T find_pred(Entry_T en, char *key) 
    {
     if (!en->next) return en; // end of list, not found
     if (strcmp(en->next->key, key)) return en;
     return find_pred(en->next, key);
    }
    

    und zwar an den Stellen en->next->next und en->next->key anscheinden mag er diese doppelte Verzeigerunng nich

    request for member `key' in something not a structure or union

    😮 😮 😮 danke



  • compilermeldung?



  • Compiler: Default compiler
    Building Makefile: "D:\Studium\PRG2\x6\Makefile.win"
    Führt  make... aus
    make.exe -f "D:\Studium\PRG2\x6\Makefile.win" all
    gcc.exe -c assotable.c -o assotable.o -I"C:/Programme/Dev-Cpp/include"   
    
    assotable.c: In function `free_AssoTab':
    assotable.c:50: warning: passing arg 1 of `free_Entry_list' from incompatible pointer type
    
    assotable.c: In function `key_listed':
    assotable.c:68: warning: passing arg 2 of `key_listed' from incompatible pointer type
    
    assotable.c: In function `remove_AssoTab':
    assotable.c:120: warning: initialization from incompatible pointer type
    assotable.c:121: error: request for member `next' in something not a structure or union
    assotable.c:122: warning: passing arg 1 of `free_Entry' from incompatible pointer type
    assotable.c: In function `find_pred':
    assotable.c:130: error: request for member `key' in something not a structure or union
    assotable.c:131: warning: passing arg 1 of `find_pred' from incompatible pointer type
    
    make.exe: *** [assotable.o] Error 1
    
    Ausführung beendet
    


  • Bastle nun schon seit heut morgen dran, keiner nen Schimmer warum zb en->next->nex t nicht geht?



  • Wie gesagt in deinen typedefs und structs ist der Fisch drinnen.

    Wenn das noch stimmt

    typedef struct Entry *Entry_T;
    

    und

    struct Entry 
    {
     char *key;
     void *info;
     int len;
     Entry_T *next;  // das gleiche wie struct Entry **next aber warum ?
    };
    

    und

    static Entry_T find_pred(Entry_T en, char *key)
    

    dann ist en->next ein pointer auf einen pointer auf struct Entry und es müsste heissen

    if (strcmp(en->(*next)->key, key)) return en;
    

    BTW: So wie dein code aussieht würde ich die compilerwarnungen sehr ernst nehmen sonst wird das nichts

    Kurt



  • Zu nächst vielen Dank, für die Mühe, ich habe jetzt eine Lauffähige version hinbekommen.

    Dein Vorschlag

    if (strcmp(en->(*next)->key, key)) return en;
    

    hatte ich auch versucht funktionierte aber nicht...
    Stattdessen geht aber

    if (strcmp((*en->next)->key, key)) return en;
    

    ob das letzendlich richtig ist werde ich sehen...
    Das hinzufügen und auslesen aus der Hashliste funktioniert auf jedenfall bereits...

    Bis hoffentlich net später 😃 😛 und vielen Dank erstma noch...

    dt


Anmelden zum Antworten