wxwidgets Problem mit Programm
-
Hallo!
Hab mich hier gerade erst registriert, da ich ein Problem mit einem Programm habe.
Es handelt sich dabei um eine numerische Integration.
Ich habe das Programm schon als Konsolen-Programm geschrieben und da funktioniert es auch perfekt. Dabei werden die berechneten Werte in eine .txt Datei gespeichert.
Jetzt soll es aber auch eine GUI bekommen. Da ich ein Programmieranfänger bin habe ich von wxwidgets auch nicht so viel ahnung.Also habe ich mal herumprobiert, einfach einen Knopf erstellt, wenn der Knopf gedrückt wird soll das Programm die Werte in eine .txt Datei speichern. Das ganze also noch ohne direkte Eingabe von Werten. Dabei habe ich die Klasse und die Methoden aus dem OOP-Programm in das GUI-Programm eingefügt. Das ganze funktioniert auch, allerdings nur bei bestimmten Werten.
Hier mal der Code:
#include "wxVersuchFrm.h" #include "rakete.h" #include <fstream> #include <iostream> using namespace std; //---------------------------------------------------------------------------- // wxVersuchFrm //---------------------------------------------------------------------------- BEGIN_EVENT_TABLE(wxVersuchFrm,wxFrame) EVT_CLOSE(wxVersuchFrm::OnClose) EVT_BUTTON(ID_WXBUTTON1,wxVersuchFrm::WxButton1Click) END_EVENT_TABLE() wxVersuchFrm::wxVersuchFrm(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style) : wxFrame(parent, id, title, position, size, style) { CreateGUIControls(); } wxVersuchFrm::~wxVersuchFrm() { } void wxVersuchFrm::CreateGUIControls() { WxPanel1 = new wxPanel(this, ID_WXPANEL1, wxPoint(1, -2), wxSize(301, 299)); WxButton1 = new wxButton(WxPanel1, ID_WXBUTTON1, wxT("WxButton1"), wxPoint(17, 26), wxSize(75, 25), 0, wxDefaultValidator, wxT("WxButton1")); SetTitle(wxT("wxVersuch")); SetIcon(wxNullIcon); SetSize(8,8,320,334); Center(); } void wxVersuchFrm::OnClose(wxCloseEvent& event) { Destroy(); } /* * WxButton1Click */ void wxVersuchFrm::WxButton1Click(wxCommandEvent& event) { Rakete rakete1; rakete1.erzeuge(590000,90000,4000,125,3500,0.35,10.8,0); rakete1.Raketengleichung(0.1,2000); }
Die zwei Funktionen am Schluss (erzeuge(...) und Raketengleichung(...)) sind aus meiner Klasse "Rakete".
Die Funktionen sind wie folgt definiert:
#include "rakete.h" // class's header file #include <cstdlib> #include <iostream> #include <cmath> #include <fstream> #include <iomanip> using namespace std; // Funktion : Abhängigkeit der Erdanziehung mit der Höhe float Rakete :: gravitation (float h) { float go = 9.81; float Re = 6400000; float gH; gH = (go * pow (Re,2))/ pow (Re + h,2); return gH; } // Barometrische Höhenformel laut ISA, gilt eigentlich nur bis zur Tropopause!! float Rakete :: dichte (float h) { float rho0 = 1.225; // Dichte in MSL laut ISA kg/m³ float a = 0.0065; // Temperaturgradient laut ISA K/m (bis zur Tropopause) float M = 0.02896; // molare Masse kg/mol float go = 9.81; // Erdanziehung m/s² float To = 288.15; // Temperatur in MSL laut ISA K float ho = 0; // Meereshöhe float R = 8.314; // universelle Gaskonstante für Luft J/K*mol float rhoH; // Dichte in der Höhe h if ( h < 40000 ) // Die Dichte muss ab ca 40000m auf 0 gesetzt werden, da sie sonst zu einer komplexen Zahl wird -> NAN // -> zieht alle anderen Werte mit runter!! { rhoH = rho0 * pow((1- (a * ( h - ho )/To)), (( M * go)/(R * a) - 1)); } else { rhoH = 0; } return rhoH; } // Abnahme der Masse m mit der Zeit float Rakete :: mass (float m0, float ml, float mp, float tb, float t) { float mT; mT = ( m0 - mp * t) * ( t < tb ) + ml * ( t >= tb); return mT; } // erzeuge Methode void Rakete :: erzeuge ( float x, float b, float c, float d, float e, float f, float g, float h ) // Die Parametervariablen dürfen nicht gleich sein wie die Variablen // die die Werte übernehmen { m0 = x; ml = b; mp = c; tb = d; vg = e; cw = f; Sref = g; ho = h; } // Raketengleichung void Rakete :: Raketengleichung ( float dt,int a) { float v = 0; // Anfangsgeschwindigkeit float t = 0; // Anfangszeitpunkt float vp; // Ableitung der Geschwindigkeit float dh; // Änderung der Höhe in der Zeit dt float dv; // Änderung der Geschwindigkeit in der Zeit dt float* vT; float* hT; float* T; //dient nur dazu die Zeit für die Excell Datei zu speichern vT = new float [a]; hT = new float [a]; T = new float [a]; vT [0] = 0; // Setzt Anfangszustand fest hT [0] = ho; // Setzt Anfangszustand fest T [0] = 0; for ( int i = 1 ; i < a; i++) { vp = ( (mp * vg)*(t < tb) - mass (m0,ml,mp,tb,t) * gravitation ( hT [i-1]) - (cw * dichte (hT [i-1]) * vT [i-1] * fabs (vT [i-1]) * Sref)/2) / mass (m0,ml,mp,tb,t); dv = vp * dt; vT [i] = vT [i - 1] + dv; dh = vT [i] * dt; hT [i] = hT [i - 1] + dh; t = t + dt; T [i+1] = t; } //-------------SPEICHERN IN TXT DATEI------------------ //----------------------------------------------------- // Die berechneten Daten werden in ein .txt Datei gespeichert, // abhängig von dem sich ergebenden "a" werden die Werte in einem bestimmten Intervall gespeichert ofstream program; program.open("Raketengleichung.txt"); int b; // Setzt die größe des Intervalls fest b = 1; int c = a/b; // Setzt fest wie viele Werte eingelesen werden float* velocity; // speichert die Werte der Geschwindigkeit in "velocity" velocity = new float [ c ]; velocity [0] = 0; for ( int i = 1; i < c ; i++) { velocity [i] = vT [ i * b ]; // Jeder b. Wert wird gespeichert } float* altitude; // speichert die Werte der Höhe in "altitude" altitude = new float [ c ]; altitude [0] = 0; for ( int i = 1; i < c ; i++ ) { altitude [i] = hT [ i * b ]; } float* time; // speichert die Werte der Zeit in "time" time = new float [ c ]; time [0] = 0; for ( int i = 0; i < c; i++ ) { time [i] = T [ i * b ]; } program << " " << " t " << " " << " v " << " " << " h " << endl; for ( int i = 0; i < c ; i ++ ) // Gibt die Werte in der .txt Datei { if ( altitude [i-1] < 0 ) // stoppt die Ausgabe wenn die ´Höhe negativ wird { break; } program << " " << time [i] << " " << velocity [i] << " " << altitude [i] << endl; } program.close(); delete [] hT; delete [] vT; delete [] T; }
Wenn ich in der Funktion "Raketengleichung" für "dt" = 1 und "a" = 200 eingebe funktioniert es normal, sobald ich aber ein zu großes "a" wähle oder "dt" kleiner mache (zb dt = 0.1), kommt beim Drücken des Knopfes eine Fehlermeldung.
Was könnte der Fehler sein?
Wie gesagt die Formeln usw. sind alle richtig und funktionieren normal auch.MfG md
-
Benenne mal ID_WXBUTTON1 um, in irgendwas ohne wx im Namen. Die Callback Funktion genauso.
wx als Präfix ist für wxWidgets reserviert.
-
Kommt eine Fehlermeldung - hervorragende Beschreibung, damit kann man etwas anfangen.
In Zeile 117 schreibst du mit T[i+1] = t an eine ungültige Position!
-
Fehlermeldung lautet:
wxVersuch.exe funktioniert nicht mehr
Das Programm wurde aufgrund eines Problems nicht richtig ausgeführt. Das Programm wird geschlossen und Sie werden benachrichtigt, wenn eine Lösung verfügbar ist.Das mit Zeile 117 versteh ich jetzt nicht ganz, aber es geht ja auch nicht um die Funktionen, die einwandfrei funktionieren.
Kann es sein, dass das Programm ein Problem mit dem Speicherplatz bekommt, weil dieser zum Beispiel beschränkt ist? Bei "dt" = 0.1 ergibt sich zB bei einer Flugdauer von 200s eine Arraygröße von 2000 also 2000 mal float, normalerweise ja kein Problem.
-
Wenn i = a-1 schreibst du an die Stelle T[a]. Da das Array die Länge a hat, schreibst du hinter den dir zugewiesenen Bereich. Das kann die Ursache für dein Problem sein, es könnte aber auch noch weitere Fehler geben.
Nur weil ein Programm zufällig nicht abstürzt, funktioniert es noch nicht korrekt.
-
Hey super. Das wars, Zeile 117 war wirklich das Problem.
Danke für die Hilfe.