Process terminated with status -1073741819 (0 minutes, 6 seconds)
-
Hallo an alle!
Ich habe ein großes Problem:
Ich habe eine kleine Konsolenanwendung geschrieben die mir und meinem Arbeitskollegen das leben ein wenig erleichtern soll. Und zwar soll sie einige Zeilen mit Text und Zahlen einfach ein wenig umformatieren. Das ist insofern wichtig weil das immer wieder wiederholt gemacht werden muss und sich dadurch die Arbeit enorm erleichtern lassen würde.
Das Programm soll daraus:
M Z4.3.1_Z Dist 69.53 70.00 0.10 -0.10 -0.47 -0.37
M Z4.3.2_Z Dist 69.71 70.00 0.10 -0.10 -0.29 -0.19
M Z4.3.3_Z Dist 69.69 70.00 0.10 -0.10 -0.31 -0.21
M Z4.3.4_Z Dist 69.62 70.00 0.10 -0.10 -0.38 -0.28das machen:
Mass Z4.3.1_Z Soll: 70.00 +0.10/-0.10 Ist: 69.53
Mass Z4.3.2_Z Soll: 70.00 +0.10/-0.10 Ist: 69.71
Mass Z4.3.3_Z Soll: 70.00 +0.10/-0.10 Ist: 69.69
Mass Z4.3.4_Z Soll: 70.00 +0.10/-0.10 Ist: 69.62dann soll das ganze in ein *.txt-File gespeichert werden (Die Quelldaten kommen auch aus einer TXT, allerdings aus einer anderen).
Soweit so gut.
Der Build funktioniert problemlos (ich benutze übrigens Code::Blocks), allerdings, wenn ich das Programm starten versuche scheint ein Fenster auf mit folgender Meldung:
"Die Anweisung in "0x00401522" verweist auf Speicher in "0c00672128". Der Vorgang "written" konnte nicht auf dem Speicher durchgeführt werden."
Ich bin mir dabei nicht ganz sicher ob Windows oder C::B das Fenster öffnet.
Ausserdem kann ich zwischen OK und Abbrechen wählen, wobei OK das Programm beendet und Abbrechen den Debugger startet, der aber nichts sinnvolles ausspuckt.
Zurück im C::B Fenster steht im Debug-teil noch folgende Meldung:
"Process terminated with status -1073741819 (0 minutes, 6 seconds)"Und jetz der Quellcode (er ist ein wenig schleißig, aber für meine Zwecke würde es reichen; ich hoffe ihr könnt etwas anfangen damit; und wenn ich hin und wieder etwas umständlich programmiere liegt das daran, dass ich erst vor kurzem von C auf C++ umgestiegen bin):
/* Geschrieben in Code::Blocks */ #include<stdio.h> #include<stdlib.h> #include<conio.h> #include<string> #include<fstream> #include<iostream> using namespace std; struct format { private: public: int i, j, k; int leercount, LFcount, zaehler; string aufbereitet, formatiert; string a, b, c, d, e; }; int main() { struct format X; ifstream lesen; ofstream schreiben; //Aufbereiten X.leercount=0; lesen.open("eingabe.txt"); while(!lesen.eof()) { X.aufbereitet[X.i]=lesen.get(); X.i++; if(X.aufbereitet[X.i-1]==32) { X.aufbereitet[X.i]=lesen.get(); while(X.aufbereitet[X.i]==32) { if(X.aufbereitet[X.i]==32) X.aufbereitet[X.i]=lesen.get(); } X.leercount++; X.i++; } if(X.aufbereitet[X.i-1]==10) { X.aufbereitet[X.i]=lesen.get(); while(X.aufbereitet[X.i]==10) { if(X.aufbereitet[X.i]==10) { X.aufbereitet[X.i]=lesen.get(); } } X.LFcount++; X.i++; } } //Kontrolle der Zählvariablen printf("\nKontrolle 1:\nZeilenumbrueche: %d\nLeerzeichen: %d",X.LFcount,X.leercount); getch(); //Neuzuordnen und Umformatieren der Daten while(X.zaehler<X.LFcount) { X.i=0; X.j=0; if(X.aufbereitet[X.i]==32) X.leercount++; if(X.leercount==1+(X.zaehler*8)) { X.i++; while(X.aufbereitet[X.i]!=32); { X.a[X.j]=X.aufbereitet[X.i]; X.i++; X.j++; } } if(X.leercount==3+(X.zaehler*8)) { X.i++; while(X.aufbereitet[X.i]!=32); { X.b[X.j]=X.aufbereitet[X.i]; X.i++; X.j++; } } if(X.leercount==4+(X.zaehler*8)) { X.i++; while(X.aufbereitet[X.i]!=32); { X.c[X.j]=X.aufbereitet[X.i]; X.i++; X.j++; } } if(X.leercount==5+(X.zaehler*8)) { X.i++; while(X.aufbereitet[X.i]!=32); { X.d[X.j]=X.aufbereitet[X.i]; X.i++; X.j++; } } if(X.leercount==6+(X.zaehler*8)) { X.i++; while(X.aufbereitet[X.i]!=32); { X.e[X.j]=X.aufbereitet[X.i]; X.i++; X.j++; } } X.i++; X.formatiert += ("Mass %s Soll: %s %s/%s Ist: %s\n",X.a,X.b,X.c,X.d,X.e); X.zaehler++; } schreiben.open("ausgabe.txt"); schreiben << X.formatiert; schreiben.close(); return 0; }Ich hoffe ick konnte euch mein Problem ausreichend schildern, und dass ihr mir dabei helfen könnt.
Danke im vorhinein!!!
-
Ohne mir den Code jetzt genauer angeschaut zu haben: Spätestens wenn Du einen String der Länge 0 an einer Stelle > 0 beschreibst (
X.aufbereitet[X.i]), kracht es.Stichwörter: resize, push_back
-
Eine Initialisierung der Members (struct format
würde sicherlich nicht schaden.

Mit welchem Wert für i startet den das Ganze ?
X.aufbereitet[X.i]=lesen.get();
-
Sry für doppelpost, aber als unregistrierter kann man beiträge nicht ändern...
PS: ich habe den kompletten code gepostet damit auch andere per copy-and-paste mein Problem nachvollziehen, bzw. rekonstruieren können.
Ich habe auch noch den debugger nochmal bemüht und habe einen verweis auf line 40 entdeckt, der mir vorher entgangen ist.PPS: Der Code ist deswengen nicht in cpp tags, weil ich instinktiv nach "code"-Tags gesucht habe und die cpp tags dabei einfach übersehen habe, obwohl sie direkt daneben waren.
SO!!
Danke für die Aufmerksamkeit!!
-
LordJaxom schrieb:
Ohne mir den Code jetzt genauer angeschaut zu haben: Spätestens wenn Du einen String der Länge 0 an einer Stelle > 0 beschreibst (
X.aufbereitet[X.i]), kracht es.Stichwörter: resize, push_back
Wie meinst du das? Ich dachte in cpp ändert sich die Stringlänge, bzw. der Speicherplatz den der String braucht dynamisch.
Mit resize und push_back kann ich leider NOCH nichts anfangen, da ich wie gesagt erst mit cpp angefangen hab. Einige Code-Fragmente habe ich aus dem internet und für meine zwecke angepasst, andere teile habe ich komplett neu erlernt und dann damit solang herumprobiert bis sie funktioniert haben, aber bei oben genannten Problem konnte ich bis jetzt keine lösung finden...Trotzdem mal danke für die schnelle Rückmeldung

-
Na gut; habe jetzt herausgefunden wie man struct initialisiert:
int main() { struct format X={0,0,0,0,0,0,0,0,0,0,0,0,0}; ifstream lesen; ofstream schreiben;dadurch tritt die speicherverletzung nicht mehr auf, allerdings lässt sich das programm immer noch nicht erfolgreich ablaufen. Es beendet sich immer selbst mit dem Fehlercode 3 (0x3).
vl. weiß noch jemand etwas mehr...
Jedenfalls mal danke mit der struktur!
-
Warum benutzt du zur Aufarbeitung nicht std::string aus <string>? Dann musst du dir nicht solche Umstände machen.
-
Wie schon zweimal gesagt... ich kenn mich mit cpp leider nicht wirklich aus
mein programmieren in dem bereich verhält sich wie die Evolution: erst mal ein wenig programmiern, dann schaun obs geht, dann weiterprogrammiern, und falls später ein besserer Weg gefunden wird wird der alte, schlechte dadurch meistens ersetzt. Meistens deswegen, weil wenn ich später etwas herausfinde wie's besser gegangen wäre, ich aber den ganzen Code dafür umwerfen müsste, es aber umständlich auch funktioniert, werde ich es nicht tun.Und nun zu deiner Antwort:

Was meinst du damit? <string> ist implementiert, was soll ich bitte anders machen?
danke für die hilfe

-
Ungefähr das meinte ich.
#include<string> #include<fstream> using namespace std; int main() { ifstream lesen("eingabe.txt"); ofstream schreiben; string eingabe; string eingabeVect[9]; int temp1 = 0; int temp2 = 0; schreiben.open("ausgabe.txt"); while(getline(lesen, eingabe)) { for (int i = 0; i < 9; i++) { temp1 = temp2+1; if (temp2 <= eingabe.length()) temp2 = eingabe.find(" ", temp1); if (temp2 > temp1) eingabeVect[i] = eingabe.substr(temp1, temp2-temp1); else eingabeVect[i] = " "; } temp1 = 0; temp2 = 0; schreiben << "Mass " << eingabeVect[1] << " Soll: " << eingabeVect[4] << " +"; schreiben << eingabeVect[5] << "/" << eingabeVect[6] << " Ist: " << eingabeVect[3] << "\n"; } schreiben.close(); lesen.close(); return 0; }
-
Erstmal danke an matze-o, dass er mir ein fertiges programm geliefert hat; echt super von dir

leider ist das programm für mich noch nicht ganz brauchbar und deswegen werde ich es ein wenig modifizieren müssen.
Nach einigen Testläufen hat sich folgendes herausgestellt: dein Programm kann leider nicht mit uberschüssigen Leerzeichen/Linefeeds umgehen (dafür war in meinem Programm die "Aufbereitung gedacht; dass sie alles auf ein grundformat gebracht hat mit dem der Rest des Programms unter allen Umständen weiterarbeiten kann.)
Und das zweite: Hin und wieder gibt es keine untere Toleranz. Das Programm muss also die Anzahl der einzelnen, von Leerzeichen getrennten, Stellen herausfinden und dann, wenn eine zu wenig ist, dann fehlt die Toleranz und wird dementsprechend anders Ausgegeben (Dierer teil fehlt in meinem Code auch noch).Naja; erstmal danke für die Hilfe und wenn ich auf gröbere Probleme bei meiner Modifikation stoße melde ich mich onehin wieder.
Noch ein großes Lob an das Forum und die Mitgleider die so schnell bereit waren mir zu helfen

LG Austrian
-
Wie zu erwarten melde ich mich wieder zurück

Folgendes problem:
habe dieses Codesegmet hier:while(eingabe[j]!=10) { if(eingabe[j]==32) { if(eingabe[j+1]==32) { eingabe.erase(j,1); } } j++; }in das Programm von matze-o direkt vor der for-schleife eingefügt um den String von überschüssigen Leerzeichen zu "reinigen". Das ergebnis war ein fehlerfreier ausführbarer Code mit einer Macke: Die Ausgabe bleibt komplett leer, bzw wird gelöscht. Wenn bereits etwas enthalten war wird es komplett rausgelöscht...
ich habe WIRKLICH versucht das problem zu lösen, aber es besteht für mich irgendwie kein logischer Zusammenhang zwischen meinem Code und dem Problem.Bitte um Ratschläge!
DANKE
-
Austrian schrieb:
ich habe WIRKLICH versucht das problem zu lösen, aber es besteht für mich irgendwie kein logischer Zusammenhang zwischen meinem Code und dem Problem.
Und für mich besteht kein logischer Zusammenhang zwischen deinem Code und dem Herauslöschen von Leerzeichen. Da wird wohl das Problem liegen.
-
Der zusammenhang ergibt sich über die Zahl 32
sinn des Codes: Wenn ein leerzeichen(ASCII 32) gefunden wird, dann soll der Code schauen ob danach noch ein Leerzeichen kommt und gegebenenfalls eleminieren.
Das ganze noch bis Stringende (wert in while schleife hab ich inzwischen auf 0 korrigiert damit er am stringende, als bei der escape-sequenz, aufhört) durchführen und schon hat man theoretisch einen sauberen string mit nur jeweils einem Leerzeichen zwischen den Abschnitten.Das ganze hat mir aber noch immer nicht weitergeholfen.
Trotzdem danke.
-
Austrian schrieb:
Der zusammenhang ergibt sich über die Zahl 32
Ich kann ASCII. Wenn dir jemand im Forum so etwas schreibt wie ich, dann steckt da meistens mehr dahinter und ist als Aufforderung gedacht, mehr darüber nachzudenken.
Außerdem: Warum 32 schreiben, wenn du auch ' ' schreiben könntest? Dann muss der Leser weder ASCII auswendig können, noch bist du überhaupt darauf angewiesen, dass die Zielplattform diese Codierung benutzt (könnte ja z.B. EBCDIC verwenden).
Aber gucken wir es uns genauer an:
sinn des Codes: Wenn ein leerzeichen(ASCII 32) gefunden wird, dann soll der Code schauen ob danach noch ein Leerzeichen kommt und gegebenenfalls eleminieren.
Und wenn 3 Leerzeichen nacheinander kommen? Was ist, wenn j+1 hinter dem Stringende ist?
Das ganze noch bis Stringende (wert in while schleife hab ich inzwischen auf 0 korrigiert damit er am stringende, als bei der escape-sequenz, aufhört)
Wie kommst du darauf, dass am Ende des Strings 0 oder 10 stünde?
durchführen und schon hat man theoretisch einen sauberen string mit nur jeweils einem Leerzeichen zwischen den Abschnitten.
Nein, siehe oben.
-
Hier der neue, verbesserte Code.
while(eingabe[j]!=0) { if(eingabe[j]==32) { do { if(eingabe[j+1]==32) { eingabe.erase(j,1); } } while(eingabe[j+1]==32) if(eingabe[j+1]==0) eingabe.erase(j-1,1); } j++; }Um eines gleich klarzustellen: Ja, ich denke oft einfach viel zu umständlich und Ja, ich mache sehr viele (Anfänger)fehler und Ja, ich lasse mich gern belehren, aber das ist noch lange kein grund gleich so bissig zu sein (siehe:
Ich kann ASCII. Wenn dir jemand im Forum so etwas schreibt wie ich, dann steckt da meistens mehr dahinter und ist als Aufforderung gedacht, mehr darüber nachzudenken.
Meine Erklärungen sind nicht geschrieben um dir ASCII zu erklären, sondern meine irrsinnigen und oft umständliche Denkweisen, und natürlich lasst sich das viel einfacher, schneller und schöner machen, aber das wusste ich doch vorher nicht

Abgesehen davon gehe ich nicht davon aus dass das programm auf einer ASCII verstehenden plattform laufen wird,sondern ich weiß es.Zu deinem Einwand bez. der 3 leerzeichen: Du hast recht, ich hab die innere Schleife vergessen; jetzt sollten alle leerzeichen bis auf eines verschwinden.
Zum eingabe[j+1] hinter stringende problem: Der string muss doch EIGENTLICH (und ich sag jetz eigentlich weil ich mir nicht sicher bin) mit einer NULL aufhören; sprich 0 oder "\0", oder? Das heißt: selbst wenn das letzte zeichen vor der null ein leerzeichen ist kann man mit j+1 nicht über den string hinausgreifen, sondern nur auf die Null. (Ausserdem habe ich jetzt noch eine If-anweisung eingefügt die so eine Null entfernen müsste).
Soweit so gut.
Trotz allem danke für das Feedback und in weiterer Hoffnung auf Hilfe mit meinem Speicherproblem.

-
Austrian schrieb:
Zum eingabe[j+1] hinter stringende problem: Der string muss doch EIGENTLICH (und ich sag jetz eigentlich weil ich mir nicht sicher bin) mit einer NULL aufhören; sprich 0 oder "\0", oder?
Eben nicht. std::string muss weder auf Null enden, noch ist verboten, dass er selber Nullzeichen enthält. Warum nutzt du für so etwas nicht die Memberfunktionen der Stringklasse? Da hast du doch alles da was du brauchst. Als Anfänger kannst du mit Integerwerten und size() eine Schleife basteln. Wenn du dir etwas mehr zutraust, nimmst du Iteratoren.
Oder du machst einen ganz anderen Ansatz: Suche (find) und entferne(erase) so lange doppelte Leerzeichen, bis keines mehr gefunden wird. Ist zwar nicht die geschickteste Methode, aber dafür ein sehr robuster Zweizeiler, bei dem nichts schiefgehen kann.
-
Erst mal danke für die ausführliche Erklärung!
Das hier hat wirklich weitergeholfen.
Ich habe mich für die robusteste Variante entschieden, da sie auch die simpelste ist. Wie du schon gesagt hast ist es wirklich ein simpler ein/dreiszeiler (mit oder ohne do-while-schleife). Die genauen funktionen habe ich hier gefunden: http://www.willemer.de/informatik/cpp/string.htm
Allerdings geht daraus nicht hervor was find zurückgibt wenn es nichts findet (wäre wichtig da es mein Ausstiegswert ist)Ich werde mich jetzt im i-net schlau machen und falls ich nichts finde komme ich ohnehin zurück.
Danke und bis bald!
-
Hier ist eine ziemlich gute, ziemlich komplette Referenz für alle C++ (und auch C) Bedürfnisse:
www.cplusplus.comDort finden wir auch den Rückgabewert von find:
Return Value
The position of the first occurrence in the string of the searched content.
If the content is not found, the member value npos is returned.Das Beispiel auf der Seite demonstriert, wie das funktioniert.
-
Erstmal wieder danke an SeppJ für die hilfe und die seitenverweise.
Hab heute wieder einiges dazugelernt.
Soweit funktioniert da programm jetzt mitdo { eingabe.erase((eingabe.find(" ")),1); } while((eingabe.find(" ")!=string::npos));als leerzeichen-filter.
Das Grundproblem bleibt allerdings weiterhin bestehen: die Ausgabedatei bleibt weiterhin leer (Bei auskommentieren des "Filters" funktioniert das Programm einwandfrei).Danke, und ich mach jetz erstmal pause.
LG Austrian
-
Könntest du mal den Sourcecode so posten, wie er jetzt ist?