Probleme mit Linker.
-
Hallo Leute,
hier mal die drei Dateien die zusammenarbeiten sollen:
ex.c#include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h" #include "set.h" /***************************************************************************** * * * ------------------------------- print_set ------------------------------ * * * *****************************************************************************/ static void print_set(const Set *set) { ListElmt *member; char *data; int size, i; /***************************************************************************** * * * Display the set. * * * *****************************************************************************/ fprintf(stdout, "Set size is %d\n", size = set_size(set)); i = 0; member = list_head(set); while (i < size) { data = list_data(member); fprintf(stdout, "set[%03d]=%s\n", i, data); member = list_next(member); i++; } return; } /***************************************************************************** * * * ------------------------------- match ------------------------------ * * * *****************************************************************************/ int match(const void *key1, const void *key2) { /***************************************************************************** * * * Determine whether two strings match. * * * match: return 1; else return 0 * * * *****************************************************************************/ return !memcmp(key1, key2, sizeof (int)); } /***************************************************************************** * * * --------------------------------- main --------------------------------- * * * *****************************************************************************/ int main(int argc, char **argv) { Set set, set1, set2, set3; char *audi1, *audi2, *chrysler1, *chrysler2; char *bmw1, *bmw2, *bugatti1, *bugatti2; char *vw1, *vw2; char *data; int retval, i; /***************************************************************************** * * * Initialize the Set set. * * * *****************************************************************************/ set_init(&set, match, free); /***************************************************************************** * * * Perform some set operations. * use Set set ! * * * *****************************************************************************/ fprintf(stdout, "Inserting the members Audi, BMW, Chrysler\n"); // Inserting "Audi" if ((audi1 = (char *) malloc(sizeof ("Audi"))) == NULL) return 1; strcpy(audi1, "Audi"); /* füge "Audi" in die Liste set ein; * bei Fehler während der Speicherreservierung: return 1 * wenn Audi bereits in der Liste enthalten: gib Datenspeicherplatz frei */ if ((retval = set_insert(&set, audi1)) < 0) { return 1; } else if (retval == 1) { free(audi1); } // Inserting "BMW" if ((bmw1 = (char *) malloc(sizeof ("BMW"))) == NULL) return 1; strcpy(bmw1, "BMW"); if ((retval = set_insert(&set, bmw1)) < 0) { return 1; } else if (retval == 1) { free(bmw1); } // Inserting "Chrysler" if ((chrysler1 = (char *) malloc(sizeof ("Chrysler"))) == NULL) return 1; strcpy(chrysler1, "Chrysler"); if ((retval = set_insert(&set, chrysler1)) < 0) { return 1; } else if (retval == 1) { free(chrysler1); } print_set(&set); /*****************************************************************************/ fprintf(stdout, "\nInserting the same members again\n"); // Inserting "Audi" if ((audi1 = (char *) malloc(sizeof ("Audi"))) == NULL) return 1; strcpy(audi1, "Audi"); if ((retval = set_insert(&set, audi1)) < 0) { return 1; } else if (retval == 1) { free(audi1); } // Inserting "BMW" if ((bmw1 = (char *) malloc(sizeof ("BMW"))) == NULL) return 1; strcpy(bmw1, "BMW"); if ((retval = set_insert(&set, bmw1)) < 0) { return 1; } else if (retval == 1) { free(bmw1); } // Inserting "Chrysler" if ((chrysler1 = (char *) malloc(sizeof ("Chrysler"))) == NULL) return 1; strcpy(chrysler1, "Chrysler"); if ((retval = set_insert(&set, chrysler1)) < 0) { return 1; } else if (retval == 1) { free(chrysler1); } print_set(&set); /*****************************************************************************/ fprintf(stdout, "\nRemoving Audi\n"); set_remove(&set, (void **) &audi1); free(audi1); print_set(&set); /*****************************************************************************/ fprintf(stdout, "\nRemoving all members\n"); while (set_size(&set) > 0) { if (list_rem_next(&set, NULL, (void **) &data) == 0) free(data); } print_set(&set); /***************************************************************************** * * * Initialize the two sets set1 and set2. * * * *****************************************************************************/ set_init(&set1, match, free); set_init(&set2, match, free); /***************************************************************************** * * * Perform some set operations. * * * *****************************************************************************/ /* Operations for SET1*/ fprintf(stdout, "\nInserting the members Audi, BMW, Chrysler in set1\n"); // Inserting "Audi" if ((audi2 = (char *) malloc(sizeof ("Audi"))) == NULL) return 1; strcpy(audi2, "Audi"); if ((retval = set_insert(&set1, audi2)) < 0) { return 1; } else if (retval == 1) { free(audi2); } // Inserting "BMW" if ((bmw2 = (char *) malloc(sizeof ("BMW"))) == NULL) return 1; strcpy(bmw2, "BMW"); if ((retval = set_insert(&set1, bmw2)) < 0) { return 1; } else if (retval == 1) { free(bmw2); } // Inserting "Chrysler" if ((chrysler2 = (char *) malloc(sizeof ("Chrysler"))) == NULL) return 1; strcpy(chrysler2, "Chrysler"); if ((retval = set_insert(&set1, chrysler2)) < 0) { return 1; } else if (retval == 1) { free(chrysler2); } fprintf(stdout, "Set 1 for testing unions and differences\n"); print_set(&set1); /*****************************************************************************/ fprintf(stdout, "\nTesting whether Set 1 equals itself..."); retval = set_is_equal(&set1, &set1); //fprintf("Value=%d (1=OK)\n", retval); /*****************************************************************************/ /* Operations for SET2*/ fprintf(stdout, "\nInserting the members Bugatti, VW, BMW in Set 2\n"); // Inserting "Bugatti" if ((bugatti1 = (char *) malloc(sizeof ("Bugatti"))) == NULL) return 1; strcpy(bugatti1, "Bugatti"); if ((retval = set_insert(&set1, bugatti1)) < 0) { return 1; } else if (retval == 1) { free(bugatti1); } // Inserting "VW" if ((vw1 = (char *) malloc(sizeof ("VW"))) == NULL) return 1; strcpy(vw1, "VW"); if ((retval = set_insert(&set2, vw1)) < 0) { return 1; } else if (retval == 1) { free(vw1); } // Inserting "BMW" if ((chrysler2 = (char *) malloc(sizeof ("Chrysler"))) == NULL) return 1; strcpy(chrysler2, "Chrysler"); if ((retval = set_insert(&set2, chrysler2)) < 0) { return 1; } else if (retval == 1) { free(chrysler2); } fprintf(stdout, "Set 1 for testing unions and differences\n"); print_set(&set2); fprintf(stdout, "Set 2 for testing unions and differences\n"); print_set(&set2); /*****************************************************************************/ fprintf(stdout, "\nDetermining the union of the two sets Set 1 and Set 2\n"); if (set_union(&set, &set1, &set2) != 0) return 1; print_set(&set); /*****************************************************************************/ fprintf(stdout, "\nDestroying the union-set\n"); /***************************************************************************** * * * Initialize the Set set. * * * *****************************************************************************/ set_init(&set, match, free); fprintf(stdout, "\nDetermining the difference of the two sets set1 and set2\n"); set_difference(&set, &set1, &set2); print_set(&set); /*****************************************************************************/ fprintf(stdout, "\nTesting whether VW is in difference...Value=%d (0=OK)\n", set_is_member(&set, "VW")); fprintf(stdout, "\nTesting whether Chrysler is in difference...Value=%d (1=OK)\n", set_is_member(&set, "Chrysler")); /*****************************************************************************/ fprintf(stdout, "\nRemoving all members from Set 2\n"); while (set_size(&set2) > 0) { if (list_rem_next(&set2, NULL, (void **) &data) == 0) free(data); } print_set(&set2); /*****************************************************************************/ fprintf(stdout, "\nDetermining the difference of the two sets set1 and set2\n"); set_difference(&set, &set1, &set2); /* Print the Set */ print_set(&set); /***************************************************************************** * * * Destroy the sets. * * * *****************************************************************************/ fprintf(stdout, "\nDestroying the sets\n"); //set_destroy(); return 0; }
list.h
/***************************************************************************** * * * -------------------------------- list.h -------------------------------- * * * *****************************************************************************/ #ifndef LIST_H #define LIST_H #include <stdlib.h> /***************************************************************************** * * * Define a structure for linked list elements. * * * *****************************************************************************/ typedef struct ListElmt_ { void *data; struct ListElmt_ *next; } ListElmt; /***************************************************************************** * * * Define a structure for linked lists. * * * *****************************************************************************/ typedef struct List_ { int size; int (*match)(const void *key1, const void *key2); void (*destroy)(void *data); ListElmt *head; ListElmt *tail; } List; /***************************************************************************** * * * --------------------------- Public Interface --------------------------- * * * *****************************************************************************/ void list_init(List *list, void (*destroy)(void *data)); void list_destroy(List *list); int list_ins_next(List *list, ListElmt *element, const void *data); int list_rem_next(List *list, ListElmt *element, void **data); #define list_size(list) ((list)->size) #define list_head(list) ((list)->head) #define list_tail(list) ((list)->tail) #define list_is_head(list, element) ((element) == (list)->head ? 1 : 0) #define list_is_tail(element) ((element)->next == NULL ? 1 : 0) #define list_data(element) ((element)->data) #define list_next(element) ((element)->next) #endif
set.h
/***************************************************************************** * * * -------------------------------- set.h --------------------------------- * * * *****************************************************************************/ #ifndef set_h #define set_h #include <stdlib.h> #include "list.h" /***************************************************************************** * * * Implement sets as linked lists. * * * *****************************************************************************/ typedef List Set; /***************************************************************************** * * * --------------------------- Public Interface --------------------------- * * * *****************************************************************************/ void set_init(Set *set, int (*match)(const void *key1, const void *key2), void (*destroy)(void *data)); #define set_destroy list_destroy int set_insert(Set *set, const void *data); int set_remove(Set *set, void **data); int set_union(Set *setu, const Set *set1, const Set *set2); int set_intersection(Set *seti, const Set *set1, const Set *set2); int set_difference(Set *setd, const Set *set1, const Set *set2); int set_is_member(const Set *set, const void *data); int set_is_subset(const Set *set1, const Set *set2); int set_is_equal(const Set *set1, const Set *set2); #define set_size(set) ((set)->size) #endif
Ich bekomme aber irgendwie ständig diese Fehlermeldung: "undefined reference to `_set_insert'". Und das natürlich mit allen Methoden aus list.h und set.h.
Google sagte mir, dass ich die Dateien im Projekt einbinden muss aber das hab ich auch gemacht...vllcht hat jemand eine Idee
Danke
Gruß Fabian
-
Wo sind denn deine Definitionen dieser Funktionen? Ich kann sie nirgendwo sehen. Der Linker auch nicht. Das wird das Problem sein.
Lies bitte auch dringend mal den dritten Link in meiner Signatur durch!
-
Danke für die schnelle Antwort. Heißt das, dass in der list.h und set.h die Methoden nicht richtig definiert sind?
Gruß Fab
-
FabianL schrieb:
Danke für die schnelle Antwort. Heißt das, dass in der list.h und set.h die Methoden nicht richtig definiert sind?
Achso und sorry für die falsche Formatierung....
Gruß Fab
-
Achso das hab ich wahrscheinlich hier noch in der set.c:
/***************************************************************************** * * * -------------------------------- set.c --------------------------------- * * * *****************************************************************************/ #include <stdlib.h> #include <string.h> #include "list.h" #include "set.h" /***************************************************************************** * * * ------------------------------- set_init ------------------------------- * * * *****************************************************************************/ void set_init(Set *set, int (*match)(const void *key1, const void *key2), void (*destroy)(void *data)) { /***************************************************************************** * * * Initialize the set. * * * *****************************************************************************/ list_init(set, destroy); set->match = match; return; } /***************************************************************************** * * * ------------------------------ set_insert ------------------------------ * * * *****************************************************************************/ int set_insert(Set *set, const void *data) { /***************************************************************************** * * * Do not allow the insertion of duplicates. * * * *****************************************************************************/ if (set_is_member(set, data)) return 1; /***************************************************************************** * * * Insert the data. * * * *****************************************************************************/ return list_ins_next(set, list_tail(set), data); }
Da sind natürlich alle aufgeführt (hab das jetzt mal gekürzt)
-
Du musst noch eine Datei set.c haben, in der der Code steht
... int set_insert(Set *set, const void *data) { hier steht der Code, .... return } ...
Diese Datei(en) musst du deinem Projekt oder Makefile noch mitteilen.
-
Hallo,
Auch wenn das ein wenig OT ist, darf ich anmerken, dass du den Code zum Anlegen eines Fahrzeugs in eine Funktion auslagern solltest? Du hast ja ein deinem Monster von Main() zigmal das gleiche stehen.
Das wird deinen Code deutlich kleiner und leichter lesbar/wartbarer machen.
Grüße
-
In Headerdateien stehen Deklarationen, bei Funktionen auch Prototypen genannt und keine Definitionen.
Dem Compiler musst du alle *.c Dateien explizit angeben und für die Headerdateien einen Suchpfad. Normalerweise macht sowas für dich die IDE oder du gibst es in einem makefile an.
Dein beschriebener Fehler deutet an, dass der Linker die Definition der Funktion ( aus der *.c Datei ) nicht finden kann, d.h. der Compiler hat hier nichts übersetzt ( weil der diese Datei auch nicht finden konnte, weil du sie ihm nicht angegeben hast ).