First Defined Here und multiple definition of new_measure/delete_measure
-
Hallo Leute,
First Defined Here und multiple definition of new_measure/delete_measure
... sind die Fehlermeldungen meines Compilers. Aber ich habe die Funktion nicht das erste mal dort definiert, sondern bereits in der Measure.h ...
#ifndef MEASURE_H_ #define MEASURE_H_ #define Measure struct measure #define maxNameLength 20 #define maxDescriptionLength 100 #define maxHtmlLength 1000 Measure { // For identification unsigned int id; // For configuration and usability char name[maxNameLength]; char description[maxDescriptionLength]; char html[maxHtmlLength]; // For optimization short int active; short valid; short fixed; }; Measure * new_measure (int i, char n[maxNameLength] , char d[maxDescriptionLength],char h[maxHtmlLength]); void delete_measure (Measure* m); #endif /*MEASURE_H_*/
... und so sieht die Measure.c Datei aus.
#include "Measure.h" Measure * new_measure (int i, char n[maxNameLength] , char d[maxDescriptionLength],char h[maxHtmlLength]){ Measure* m; m=(Measure*) malloc(sizeof(Measure)); m->id=i; strcpy (m->name,n); strcpy (m->description,d); strcpy (m->html,h); m->active=1; m->valid=1; m->fixed=0; return m; }; void delete_measure (Measure* m) { free (m); };
Was hab ich falsch gemacht? In einer anderen "Klasse" (ich weiß, es gibt in C keine Klassen) hat es auf genau diese Weise funktioniert.
Vielen Dank,
Peilnix
-
Measure {
// For identification
unsigned int id;// For configuration and usability
char name[maxNameLength];
char description[maxDescriptionLength];
char html[maxHtmlLength];// For optimization
short int active;
short valid;
short fixed;};
da fehlt was. es sollte besser so aussehen:
typedef struct Measure_t { ... } Measure;
-
... erst mal danke für die Antwort. Ich habe es ausprobiert und die
#define Measure struct measure gelöscht ... mit dem Ergebnis, dass anschließend die "Cell.h" Measure nicht mehr kannte. Also habe ich dort das gleiche gemacht. (#define löschen, typedef struct cell {...} Cell;)
und zack, war das erste problem wieder da. kann es was mit forwarddeclaration zu tun haben
Peilnix
-
peilnix schrieb:
und zack, war das erste problem wieder da. kann es was mit forwarddeclaration zu tun haben
kann sein, mach in alle .h's sogennante 'include guards' rein
--> http://en.wikipedia.org/wiki/Include_guard
dann kannst du's kreuz und quer #includen.
wichtig auch: niemals die structs und typedefs nochmals (doppelt) irgendwo anlegen.
--> http://en.wikipedia.org/wiki/One_Definition_Rule
-
includeguards überall, keine doppelte typedef ...
und dann: plötzlich sah ich in der main.c ein include Measure.c in der ich keinen includeguard eingebaut hatte ... !!!
ich wäre niemals drauf gekommen (auch wenn ich die guards und odr (wenn auch nicht unter diesen namen) kannte.
deshalb vielen DANK, lieber undertaker!
yippieh (kopfrot abschwell, durchatmen ... seufz, freudentanz),
der peilnix
-
peilnix schrieb:
und dann: plötzlich sah ich in der main.c ein include Measure.c in der ich keinen includeguard eingebaut hatte ... !!!
Ich hoffe du hast das durch ein Include des Headers ersetzt, nicht die Implementation mit Include-Guards bestückt!?
-
... ich habe tatsächlich nur c_vitro.h included.
Naja, jetzt habe ich den abstrakten Datentyp Measure fertiggestellt und mit einer Funktion
print_measure
versehen ...
#Measure.h #ifndef MEASURE_H_ #define MEASURE_H_ #include "c_vitro.h" Measure { // For identification unsigned int id; // For configuration and usability char name[maxNameLength]; char description[maxDescriptionLength]; char html[maxHtmlLength]; // For optimization short active; short valid; short fixed; }; Measure * new_measure (int i, char n[maxNameLength] , char d[maxDescriptionLength],char h[maxHtmlLength]); void delete_measure (Measure* m); void print_measure (Measure* m); char* string_measure (Measure* m); #endif /*MEASURE_H_*/ ///////////////////////////////////////////////////////////// #Measure.c #include "Measure.h" Measure* new_measure (int i, char n[maxNameLength] , char d[maxDescriptionLength],char h[maxHtmlLength]){ Measure* m; m=(Measure*) malloc(sizeof(Measure)); m->id=i; strcpy (m->name,n); strcpy (m->description,d); strcpy (m->html,h); m->active=1; m->valid=1; m->fixed=0; return m; } void delete_measure (Measure* m) { free (m); } void print_measure (Measure* m) { char* result=string_measure (m); puts (result); } char* string_measure (Measure* m) { char* result=""; char* temp=""; sprintf (temp, "Measure %s.\nId of measure is %d.\n",m->name,m->id); strcat (result, temp); sprintf (temp, "Description: %s.\nHTML-Doc: %s.\n",m->description,m->html); strcat (result, temp); if (m->active) strcat (result, "State:Active, "); else strcat (result, "State:\nNot Active, "); if (m->valid) strcat (result, "valid, "); else strcat (result, "not valid, "); if (m->fixed) strcat (result, "fixed.\n"); else strcat (result, "not fixed.\n"); return result; } /////////////////////////////////////////////////// # c_vitro.h #ifndef C_VITRO_H_ #define C_VITRO_H_ #include <time.h> #include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h> #define Measure struct measure #define Cell struct cell #define maxNameLength 20 #define maxDescriptionLength 100 #define maxHtmlLength 1000 #include "Measure.h" #endif /*C_VITRO_H_*/ ///////////////////////////////////////////7 #c_vitro.c #include "c_vitro.h" int main () { Measure* m=new_measure (1, "Darth" , "Vader", "<html><b>Darth Vader</b></html>"); print_measure (m); delete_measure (m); return 0; }
Alles wird einwandfrei compiliert und siehe da: segmentation fault ...
Meine Güte, da waren mir die CompilerErrors doch sympathischer, da waren mehr Details drin enthalten
Aber was dieser runTimeError nun bedeutet, da habe ich nun wirklich keine Idee. Was habe ich falsch gemacht? Wenn ich den Compiler via Shell starte mit
chess@vulcan:~/workspace/c_vitro> gcc c_vitro.c -g -o segfault
so kommt die folgende Info:
/tmp/ccOVVuP7.o: In function
main': /home/chess/workspace/c\_vitro/c\_vitro.c:5: undefined reference to
new_measure'
/home/chess/workspace/c_vitro/c_vitro.c:6: undefined reference toprint_measure' /home/chess/workspace/c\_vitro/c\_vitro.c:7: undefined reference to
delete_measure'Gut sage ich mir und kopiere nun den Inhalt von der Measure.c in die c_vitro.c und lösche anschließend Measure.c. Gesagt, getan.
Jetzt funktioniert
gcc c_vitro.c -g -o segfault
wunderbar, bzw. ohne Fehlermeldung, nur damit wieder
segmentation fault
als Fehlermeldung kommt, wenn ich ./c_vitro nutze, um das Progrämmchen zu starten.
Wo liegt das Problem?
Danke ...
Peilnix
-
Ich habe die char* in der Funktion print durch char[2000] ersetzt und jetzt funktioniert es ganz wunderbar. Auf jeden Fall ein Erfolgserlebnis ...
Lass mich raten. Dynamisch geht es, wenn ich die Größe des Ausgabetextes + 1 errechne, dann mit calloc den char reserviere und abschließend wieder free befreie?!
Das kann aber erst nach dem return statement der funktion string_measure machen ... das würde wiederum heißen, dass ich nach dem aufruf eben dieser funktion stets die funktion free aufrufe?!
Also gibt es einen sinnvollen weg, die größe des ReturnArrays dynamisch zu bestimmen (nicht wirklich wichtig, aus reinem interesse ...)
Grüße an alle,
Peilnix
-
Benutz dir [cpp]-Tags (nicht die [code]-Tags) und schau, dass du sie auch richtig verwendest. So will man den Code von dir nicht gerne lesen. Du kannst deine Beiträge auch editieren.
-
Hallo Tim,
Du hast recht, das ist so deutlich übersichtlicher. Danke für den Hinweis.
Peilnix