Memory error bei verketteter Liste !
-
So die Damen und Herren,
hab mal ein kleines Problem und zwar wollte ich als Klausurvorbereitung ein Porgramm schreiben, dass mir aus einer txt ein paar Daten einließt und dann verarbeitet. WICHTIG!!! Frag mich nicht warum ich es so gemacht habe, ich hab es einfach - ich weiß das es auch leichter geht.
Das Programm stürzt beim 2. Durchlauf der Schleife ab, wenn er memory reservieren will. Des Weiteren speichert er den Wert Uhrzeit nicht richtig ab. Und macht hin und wieder andere komische Sachen
also hier mal das programm und ein beispiel der txt:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define N 65 struct termin { struct termin *next; char month[20], datum[12], uhrzeit[7], was[N];}; struct termin *einlesen(FILE *fp) { struct termin *anfang, *neu, *letztes; anfang = NULL; letztes = NULL; char text[20]; while(fgets(text,N,fp) != NULL) { neu = (struct termin*)malloc(sizeof(struct termin)); if(anfang == NULL) anfang = neu; else letztes->next = neu; letztes = neu; strcpy(letztes->month, text); fgets(letztes->datum,11,fp); fgets(letztes->uhrzeit,6,fp); fgets(letztes->was,N-2,fp); letztes->next = NULL; } return anfang; } void ausgeben(struct termin *aktiv) { while(aktiv->next != NULL) { printf("Monat: %s",aktiv->month); printf("Monat: %s",aktiv->datum); printf("Monat: %s",aktiv->uhrzeit); printf("Monat: %s",aktiv->was); } return; } struct termin *suchen() { return 0; } void main() { FILE *fp; struct termin *start; fp = fopen("termine.txt","rb"); start = einlesen(fp); fclose(fp); ausgeben(start); return; }
termine.txt:
Januar
06.07.2006
12:00
Klausur Technische Mechanik
Januar
07.07.2006
13:00
Klausur Informatik----------------------------------------
Vielen Dank im Vorraus!
MfG
Micha
-
Hallo
Also bei mir stürtzt sogar der gdb ab , wenn ich versuche dein programm zu debugen.Eine Sache die schon mal gefährlich aussieht ist:
#define N 65 .... char text[20]; .... while(fgets(text,N,fp) != NULL)
Text ist nur 20 Byte, fgets kann aber bis zu 64 zeichen lesen.
Wenn man das entschärft, läuft das Programm in einer endlos schleife in der Funktion ausgeben. aktiv->next vom letzten Element ist also nicht NULL,[Edit]was kein wunder ist weil da ein aktiv = aktiv->next; fehlt[/Edit]
Momentan kann ich nur das sagen.
-
Außerdem ist die Anzahl der gelesenen Zeichen die du an fgets(... ,int num, ...) über gibst um eins zu klein weil fgets num-1 Zeichen ausliest:
fgets(letztes->datum,12,fp); fgets(letztes->uhrzeit,7,fp);
Und die Bedingung in der schleife muss lauten aktiv != NULL
und nicht aktiv->next != NULL.So geändert funktioniert das Programm bei mir.
Den Cast in:
neu = (struct termin*)malloc(sizeof(struct termin));
kannst du auch weglassen.
-
Marcin schrieb:
Also bei mir stürtzt sogar der gdb ab
der taugt eh' nix...
-
net schrieb:
Marcin schrieb:
Also bei mir stürtzt sogar der gdb ab
der taugt eh' nix...
Echte Programmier brauchen eh keinen Debugger...
-
elduderado schrieb:
printf("Monat: %s",aktiv->month); printf("Monat: %s",aktiv->datum); printf("Monat: %s",aktiv->uhrzeit); printf("Monat: %s",aktiv->was);
Darf ich fragen, wie der User noch durchblicken soll, wenn sowohl der Monat, als auch das Datum, die Uhrzeit und "was" als Monat ihm dargestellt werden? Ausserdem: Warum wechselst du in den Sprachen? Nenn doch das 1. Teil einfach monat und nicht month... Nur so der Übersichtlichkeit
-
net:
Wieso meinst du der gdb taugt nix? Das war ein scherz, oder? Ist deine Meinung, will dich auch nicht kritisieren oder so, mich interessiert nur wie du da drauf kommst. Danke.
-
Mr.PuMuKEL schrieb:
net:
Wieso meinst du der gdb taugt nix? Das war ein scherz, oder?hi,
immer wenn ich gdb's verwendet haben, haben die nur rumgezickt. einmal für msp430, dann der, der beim mimgw dabei ist und einmal für ecos/v850. dafür gibts auch noch so schreckliche sachen wie 'insight'. das läuft alles nicht richtig, ist tierisch buggy. liegt wohl daran, dass gdb ein multiplatform debugger ist und sich deshalb nicht so tief in's system eingraben kann wie er's eigentlich sollte. ist ähnlich wie mit'm gcc: gut für unix systeme aber überall anders wird der code 1.5 bis 2 mal so gross und läuft doppelt so langsam im vergleich zu kommerziellen compilern. allgemein gilt: dieser gnu-kram ist irgendwie nur bedingt zu gebrauchen...Mr.PuMuKEL schrieb:
will dich auch nicht kritisieren oder so
macht doch nix
-
hui, danke an alle .... ja zeiger und Felder können in c echt kompliziert werden
aber zum Glück ist die Klausur heute besser gelaufen.
Mit der Ausgabe (Monat), dass war nur ein Flüchtigkeitsfehler. Dank eurer Hilfe läuft es jetzt bei mir. Vielen Dank !!!
Achso @ Marcin: Ich benutze keinen reinen c compiler, sprich Visual C++ und da braucht er den cast, da malloc nur einen *void wiedergibt !!! oder lieg ich da flasch ?!?!?
-
Ich kenne mich zwar mit Visual C++ und dem Compiler den es benutzt zwar nicht aus, aber ich vermute dass es ein C++ compiler ist und deshalb verlangt er unbedingt den cast, ich verstehe dann allerdings nicht warum er nicht gegen void main(), return; protestiert. C++ Compiler sind da viel strenger.
Wie auch immer, in Standard C braucht man kein cast bei malloc weil der Ruckgabewert Zeiger vom Typ void ist und der kann in jeden anderen Zeiger ohne cast umgewandelt werden.
-
Marcin schrieb:
Ich kenne mich zwar mit Visual C++ und dem Compiler den es benutzt zwar nicht aus, aber ich vermute dass es ein C++ compiler ist und deshalb verlangt er unbedingt den cast, ich verstehe dann allerdings nicht warum er nicht gegen void main(), return; protestiert. C++ Compiler sind da viel strenger.
beim alten visual c++ (version 6) sind 2 compiler dabei. einer für c und einer für c++. .cpp dateien werden durch den c++ compiler geschickt, deshalb braucht man da ein cast bei void typen. das mit dem 'void main()' stört aber keinen von beiden. ist ja auch nicht wirklich ein problem...
-
oki vielen Dank
schönes weekend allen