free()
-
Wenn ich in Zeile 16 das %lf in %f ändere, bekomme ich zweimal Wert fuer "time: 1.000000"
(auch Code:Blocks 10.05 mit dem dazu gelieferten GCC, Windows 7 Home)Warum muss es float sein?
Warum das f hinter der 1.0?Bei deinem Original bekomme ich bei f_steps2 die 0.000000. Kann an dem %lf liegen.
-
Ist das wirklich 1:1 das Programm, welches den Fehler zeigt? Komplett mal neues Projekt angelegt, diesen Code genommen, komplett neu compiliert und dann kommt diese Ausgabe?
(Der Formatspezifizierer %lf bei f_steps2 zeugt übrigens nicht von Verständnis von printf. Er ist zwar technisch nicht direkt falsch, aber es ist nicht das was du denkst)
-
Ich habe diese Zeilen eben rauskopiert und als neues Projekt angelegt. Dabei tritt der Fehler nicht auf... Komisch.
Zu der Frage wieso 1.0f: Eigtl steht dort eine Variable die einen float-Wert beinhaltet. 1.0f habe ich nur testweise hingeschrieben, um den Fehler zu finden.
Statt dem %lf sollte ich wohl eher %e nehmen. Ist nur hängengeblieben von den anderen Versuchen.
Also den Code, den ich gerade gepostet habe, da spielt sich alles ab, was die Variablen und die Funktion betrifft:
In der Funktion f_steps habe ich testweise direkt als ersten Befehl die Ausgabe von time gefordert.
Und beim Funktionsaufruf (err = f_steps(p_step,1,1.0f)) kann ja an der Variablen auch nichts mehr geändert werden.Aber logischerweise muss der Wert von time ja irgendwo verändert werden, aber wo sollte das geschehen? Und wieso funktioniert der Code, wenn ich anstelle des floats ein double, und den Parameter als double übergebe? Und printf natürlich anpasse..
-
fabarazzi schrieb:
Statt dem %lf sollte ich wohl eher %e nehmen. Ist nur hängengeblieben von den anderen Versuchen.
Erklär mal, was gegen %f spricht. Und ich nehme schonmal vorweg: Deine Erklärung ist falsch.
Aber logischerweise muss der Wert von time ja irgendwo verändert werden, aber wo sollte das geschehen? Und wieso funktioniert der Code, wenn ich anstelle des floats ein double, und den Parameter als double übergebe? Und printf natürlich anpasse..
Du wirst irgendwo in dem Teil den du uns verschwiegen hast undefiniertes Verhalten erzeugen. Das ist eben komisch. Und deswegen wurdest du auch schon zigmal aufgefordert:
SeppJ schrieb:
Zeig mal ein vollständiges Beispiel, welches den Fehler produziert.
Aber mir ist das langsam zu blöd. Wenn du nicht geholfen werden möchtest, dann musst du dir eben selber behilflich sein.
-
Erklär mal, was gegen %f spricht. Und ich nehme schonmal vorweg: Deine Erklärung ist falsch.
Ich dachte nunmal, dass ich für einen double Wert als Formatierung entweder %lf oder %e verwende. Was daran so falsch ist, verstehe ich jetzt nicht, aber erklären kannst du es anscheinend ja auch nicht.
Wenn ich wüsste wo undefiniertes Verhalten zustande kommt, hätte ich es behoben und nicht dumm gefragt. Was eine direkt übergebene Variablen verändert, wenn der erste Befehl in der Funktion ein printf() ist, bleibt mir allerdings schleierhaft.
Ich biete dir gern meinen kompletten Code hier an, allerdings wird dort nirgends irgendetwas an der Funktion oder Variablen geändert:In Zeile 66 wird die Funktion aufgerufen:
void work(int time) { float get_time; if(time){get_time = 1;} int i,z,err; err = 0; float time_verbrauch; float new_state; float act_state; int summe_steps = 0; /*Auftrag aus ORDER holen*/ p_order = p_order_start; time_verbrauch = 0; while(p_order && !err) { printf("\nDEFINIERTE ANZAHL AN STEPS*QUANTITY %f\n\n",p_order->steps_quantity); /*Auftrag fuer Auftrag soll abgearbeitet werden*/ /*get STATUS von ORDER*/ act_state = p_order->status; /*Welcher Schrank soll gebaut werden*/ p_schrank = p_order->id; /*naechsten STEP mittels STATUS und STEP finden*/ i = 0; p_step = p_schrank->p_steps[i]; new_state = 0; while(p_step && !err) { z = 0; while(z<p_schrank->steps_quantity[i] && !err) //Solange noch nicht alle WIEDERHOLUNGEN von STEP erledigt wurden { /*Zeitverbrauch addieren*/ new_state += p_step->time; /*Fange mit Arbeit erst an, wenn aktueller Status erreicht ist*/ if(new_state>act_state && time_verbrauch<get_time) { if(p_step->time > (get_time-time_verbrauch)) //falls zeitaufwand fuer step zu groß ist { printf("%f",p_step->time); printf(" GEG %f GEG",get_time); printf("Der AS braucht zu lange\n"); err = f_steps(p_step,1,get_time-time_verbrauch); if(!err) { /*Neuer Status = alter STATUS + Zeit*/ p_order->status += p_step->time; // ODER new_state time_verbrauch += p_step->time; //Teil des Schrittes bearbeiten p_order->status = act_state + get_time; time_verbrauch = get_time; printf("\nSTEP wird teilweise ausgefuehrt\n"); printf("Und zwar: %s \n",p_step->name); } } else //Zeitaufwand fuer STEP passt noch in TIME budget { //Status bekommen err = f_steps(p_step,1,1.0f); if(!err) { /*Neuer Status = alter STATUS + Zeit*/ p_order->status += p_step->time; // ODER new_state time_verbrauch += p_step->time; } printf("\nES WIRD EIN STEP AUSGEFUEHRT, %f + %f\n",time_verbrauch, p_step->time); printf("Und zwar: %s \n",p_step->name); } } if(p_order->status == p_order->steps_quantity) //ORDER fertig { printf("Auftrag erfolgreich ausgefuehrt"); p_order_start = p_order->next_order; } //f_steps(p_step,1,p_step->time); z++; } i++; p_step = p_schrank->p_steps[i]; } printf("\nVERBRAUCHTE ZEIT: %f\n",time_verbrauch); printf("\n\n\nNEUER STATUS: %f\n\n\n",p_order->status); p_order = p_order->next_order; } switch(err) { case 0: printf("\nKein Fehler\n"); break; case 1: printf("\nKein Kapital\n"); break; case 2: printf("\nKeine Ressourcen\n"); break; } }
int f_steps(STEP *p_step, int quantity, float time) { printf("%f\n",time); /*ABHAENGIG VON ZEIT*/ int i = 0; int err = 0; /*Suche in Arbeitsschritt, welche Ressource verarbeitet wird*/ if(!p_step->p_ressources && strcmp(p_step->ressource,"")) /*Falls kein Pointer vorhanden, aber Wert existiert*/ { p_ressource = search_ressource(p_step->ressource); } else { p_ressource = p_step->p_ressources; } /*Ressource in p_ressource abgelegt (sofern es eine gibt)*/ /*Geld fuer AS vorhanden?*/ if(kapital<(quantity*time*p_step->price)) { err = 1; } /*Genuegend Ressourcen im Lager vorhanden?*/ if(p_ressource && p_ressource->stock < (quantity*time)) { err = 2; } /*Ressourcen vom Lagerbestand abziehen, Kapital abzueglich der AS-Kosten*/ if(!err) { printf("Kein Fehler %lf %f",time,p_step->price); kapital = kapital - time*p_step->price; if(p_ressource) p_ressource->stock = p_ressource->stock - (quantity*time); //!Es sollten eigtl keine 0.x Mengen abgeubcht werden koennen } return err; }
-
fabarazzi schrieb:
Erklär mal, was gegen %f spricht. Und ich nehme schonmal vorweg: Deine Erklärung ist falsch.
Ich dachte nunmal, dass ich für einen double Wert als Formatierung entweder %lf oder %e verwende.
Warum dachtest Du das denn? Nimm nicht %lf, sondern %f - fertig, %e geht natürlich auch, erzeugt aber eine andere Darstellung.
-
fabarazzi schrieb:
Erklär mal, was gegen %f spricht. Und ich nehme schonmal vorweg: Deine Erklärung ist falsch.
Ich dachte nunmal, dass ich für einen double Wert als Formatierung entweder %lf oder %e verwende. Was daran so falsch ist, verstehe ich jetzt nicht, aber erklären kannst du es anscheinend ja auch nicht.
Doch, kann er, nur wollte er dir die Möglichkeit lassen mal zu zeigen, dass du auch in der Lage bis so etwas selbst herauszufinden. Dürfte in so ziemlich jeder Doku zu printf stehen.
-
Dann bedanke ich mich gerne für diesen Tip. Allerdings benötige ich jetzt keine Ausgabe von double-Werten.
Meine Problem war die Übergabe eines float-Parameters an eine Funktion ..
-
fabarazzi schrieb:
Meine Problem war die Übergabe eines float-Parameters an eine Funktion ..
Ist dein Problem jetzt behoben?
fabarazzi schrieb:
Ich biete dir gern meinen kompletten Code hier an, ...
Auch diesen Code kann man nicht nachvollziehen, da dort kein main() vorhanden ist.
Warum muss es eigentlich float sein?
float nimmt man heutzutage nur noch wenn man sehr sehr viele Werte davon hat.
Schneller wird es mit float auch nicht, da die Berechnungen alle in double ausgeführt werden und somit jedesmal konvertiert werden muss.
-
Dann wäre es an sich ja klüger einen double zu verwenden .. Danke.
Prinzipiell muss es kein double sein. Nur würde mich interessieren, wieso es hier zu einem Problem kommt, wenn ich einen float-Wert angebe ..
Wegen der Darstellung des Codes:
Ich wollte nur das Prinzip verdeutlichen, wie ich die Funktion aufrufe und was für Parameter verwendet werden. An und für sich ist das auch kein Hexenwerk. Nur komischerweise spinnt er bei mir bei einem bestimmten Datentyp.
Ich kann leider auch nicht die komplette Funktion mit der main hier posten, da dies viel zu unübersichtlich würde. Der relevante Teil, war der Teil, den ich hier veröffentlicht habe: http://ideone.com/ZvI1CUnd da funktioniert das Ganze ja auch. Die Frage, die ich mir stelle ist: Wo ein direkt übergebener Wert an eine Funktion verändert wird, wenn die erste Anweisung in der Funktion ein printf() ist. Eigtl ist dies doch nicht möglich.
Bei meiner Frage ging es nicht um Grundverständnisfragen, oder gar einen Streit, um Formatierungsausgabemöglichkeiten.
Aber um hier nicht noch weitere genervte Kommentare zu sammeln, belasse ich es dabei und suche die Lösung des Problems selbst.
Nebenbei sei nur angemerkt, dass ich niemanden gezwungen habe mir zur helfen. Und falls jemand meint sich des öfteren aufregen zu müssen, da ihm meine Problembeschreibung nicht passt, dann sollte er es sein lassen, noch weiter unnötige Anmerkungen zu schreiben, dass er keine Lust hat zu helfen. Was daran produktiv sein soll, versteh ich nicht ganz ..
Für die anderen Tips bin ich allerdings dankbar.
-
fabarazzi schrieb:
Aber um hier nicht noch weitere genervte Kommentare zu sammeln, belasse ich es dabei und suche die Lösung des Problems selbst.
Richtig. Die Lösung des Problems liegt bei dir. Das Problem selbst auch.
Der Compiler hat immer recht.
-
fabarazzi schrieb:
... um Formatierungsausgabemöglichkeiten.
Noch einmal ganz deutlich: Wenn Du mit printf ein float oder ein double ausgibst, dann ist die richtige Formatierungsanweisung: %f
Das gilt nicht nur für float, sondern eben auch für double. Wenn Du das beachtest, sollte Dein Problem gelöst sein.
-
Belli schrieb:
Noch einmal ganz deutlich: Wenn Du mit printf ein float oder ein double ausgibst, dann ist die richtige Formatierungsanweisung: %f
Das gilt nicht nur für float, sondern eben auch für double. Wenn Du das beachtest, sollte Dein Problem gelöst sein.Das ist eben nicht das Problem das ich habe. Ich übergebe einen Floatwert und gebe ihn mit printf und %f aus und als Wert wird aber bei der Übergabe von 1.0f der Wert 0.00000 ausgegeben. Bei dem Wert 1.838 wird jetzt beispielsweise -2.00000 ausgegeben ..
-
fabarazzi schrieb:
Nebenbei sei nur angemerkt, dass ich niemanden gezwungen habe mir zur helfen. Und falls jemand meint sich des öfteren aufregen zu müssen, da ihm meine Problembeschreibung nicht passt, dann sollte er es sein lassen, noch weiter unnötige Anmerkungen zu schreiben, dass er keine Lust hat zu helfen. Was daran produktiv sein soll, versteh ich nicht ganz ..
Nein, du zwingst niemanden. Aber du erwartest Hilfe. Und dir wurde 4x erklärt, warum man dir bei der Art deiner Beiträge nicht helfen kann. Und dir wurde gesagt, was du ändern musst, damit du kompetente Hilfe bekommen kannst. Das hast du nie getan, sondern bist stattdessen beleidigt geworden. Und du hast auch tatsächlich bis jetzt keine Hilfe zu deiner eigentlichen Frage bekommen. Ob da wohl ein Zusammenhang besteht?
Naja, inzwischen dürftest du alle Helfer vergrault haben und nur noch ein paar Schaulustige anziehen, die sich an deinem nächsten Beitrag auf morbide Weise erfreuen. vielleicht hast du ja mit denen Glück, wenn du endlich mal das geforderte Minimalbeispiel bringst.
-
Ich war zu keiner Zeit beleidigt. Habe dies auch nie so rüberbringen wollen.
Das Problem habe ich jetzt gelöst.
Falls es jemanden interessiert:Dadurch, dass die Funktion in einer anderen .c-Datei definiert ist, muss ich in der .c-Datei, in der die Funktion aufgerufen wird, die Funktion im entsprechenden .h-File als extern deklarieren (extern int f_steps(STEP *,int,float)). Und diese Deklaration ist mir in die falsche header-Datei gerutscht. Dadurch hat er die Funktion zwar aufgerufen, wusste aber nicht, welche Datentypen die Parameter besitzen ..
-
Das extern ist bei Funktionsdeklarationen nicht nötig.
Und der Compiler meckert das auch an, wenn er nicht genau weiss wie die Funktion deklariert ist.
Behandele Warnungen wie Fehler!
-
fabarazzi schrieb:
Dadurch, dass die Funktion in einer anderen .c-Datei definiert ist, muss ich in der .c-Datei, in der die Funktion aufgerufen wird, die Funktion im entsprechenden .h-File als extern deklarieren (extern int f_steps(STEP *,int,float)). Und diese Deklaration ist mir in die falsche header-Datei gerutscht. Dadurch hat er die Funktion zwar aufgerufen, wusste aber nicht, welche Datentypen die Parameter besitzen ..
Das ist ja fein. Und nun guck mal in den Code den du uns gezeigt hast. Diese entscheidende Stelle war kein einziges Mal dabei. Dabei hätten dir das 80% der Leser spätestens beim zweiten Blick auf diesen Fehler sofort erklären können. Und nun verstehst du hoffentlich, warum dir niemand helfen konnte.
-
Ok, entfernt. Danke
-
Wie oft hast du die Funktion denn vorher aufgerufen. Steht die irgendwo im Quelltext mit etwas anderem als 1.0f ?
Wenn der Compiler nicht weiss, wie die Funktion deklariert ist, nimmt er an, dass das was du geschrieben hast richtig ist.
Er gibt aber eine Warnung.
Wenn du beim ersten mal ein int oder double hast, wandelt der Compiler bei den nächsten Aufrufen den Parameter halt in int (oder double) und übergibt ihn an die Funktion.
Wenn der Compiler keine Fehler meldet, bedeutet das nicht, dass das Programm fehlerfrei ist.
Und wenn keine Warnung kommt, setz den Warnlevel hoch und schalte alle Warnungen an.
-
Die Funktion wurde dort das erste Mal aufgerufen - testweise auch nur mit 1.0f. Das Problem war die Deklaration .. jetzt funktionierts ja. Wie gesagt, hab die Deklaration in der falschen .h-Datei gehabt, die damit überhaupt nichts zu tun hatte..
SeppJ schrieb:
Das ist ja fein. Und nun guck mal in den Code den du uns gezeigt hast. Diese entscheidende Stelle war kein einziges Mal dabei. Dabei hätten dir das 80% der Leser spätestens beim zweiten Blick auf diesen Fehler sofort erklären können. Und nun verstehst du hoffentlich, warum dir niemand helfen konnte.
An die .h-Datei hatte ich anfangs selber nicht gedacht.. sry.. dachte zunächst, dass die Aufteilung in zwei verschiedene .c-Dateien für sich spricht (dass entsprechende .h-Dateien vorliegen)
Also nochmal sry für die Missverständnisse