Bei Aufruf von new wird das Programm beendet
-
Hi,
ich hab jetzt schon einiges an Literatur durchforstet, komme aber nicht weiter.
Folgendes Problem:
Ich habe ein lauffähiges Konsolenprogramm geschrieben. Jetzt wollte ich die Klassen feiner unterteilen, wodurch Einfachvererbungen (ohne irgendwelche Überladungen) entstanden sind. Der Compiler findet's auch gut aber bei der Ausführung wird das Programm verlassen, sobald der new-Operator aufgerufen wird. Ganz ohne Fehlermeldung.Der erste Aufruf findet hier statt:
char* buffer;
...
buffer = new char[size]; //size ist bekanntIm Original läuft's.
Kann mir irgendwer sagen, woran das liegt?!
Danke im Voraus!!!
-
GolanT schrieb:
Kann mir irgendwer sagen, woran das liegt?!
Nein, unmöglich. Nicht weil ich nicht will, sondern weil Du viel zu wenig Infos lieferst.
Lass das Programm mal im Debugger laufen, dann siehst Du (normalerweise) wo er aussteigt und i.A. auch eine Fehlerbeschreibung.
-
Und an zwei Zeilen die so offensichtlich zwar korrekte Syntax haben, aber nicht wirklich informativ sind, kann man einen Fehler auch schlecht erkennen. Reduzier deinen Quellcode mal fuer uns so weit, dass so wenig wie moeglich drinsteht, der Fehler aber immenroch auftritt. Oft wird schon wenn du das versuchst offensichtlich, worans gelegen hat. Wenn nicht, poste deinen Code, damit wir was handfestes haben

-
Tja, also hier die Basisklasse Parser, bei der das Programm immer aussteigt, wenn es bei dem new ist. Das hatte ich aber schon mal isoliert und da ist das Programm bei der nächsten Stelle mit einem new ausgestiegen.
#ifndef PARSER_H #define PARSER_H #include <fstream.h> using namespace std; class Parser{ public: char* buffer; static int counter, lengthstr1, lengthstr2, topIndex; Parser(); Parser(int size){ //cout<<"\ndrin Size: "<<size<<endl; buffer=new char[size]; //cout<<"\nraus\n$\t"<<buffer<<endl; }; ~Parser(){ delete[] buffer; }; char getBufferContent(int position); void readCharacter(char character); void moveContent(); int getdecAdr(); int getdecSize(); int *charhextostringint(char z); int getMaxString(ifstream &file); }; #endifDann noch ein Konstruktor aus einer abgeleiteten Klasse:
Functionparser(int size) : Parser(size){}Und die Ausgabe vom Debugger (mit der ich nix anfangen kann, weil ich den noch nie benutzt habe
)Programm exited with Code 01
Ich hoffe das sagt was aus.
Wie schon gesagt, der Compiler meckert nicht und vor der feineren Einteilung der Klassen, lief ja alles.
-
Sieht soweit sauber aus, auch wenn du zwecks besserer Kapselung deinen Membervariablen private machen solltest. Jetzt zeig usn noch den Kontext, wo du das Parserobjekt erstellst und den Konstruktor aufrufst. Vor allem die Groesse von size wuerde mich in dem Zusammenhang interessieren.
-
Ich hab's mal etwas zusammengerückt. Wir befinden uns in der "main":
1 int size; 2 Parser parser; 3 size=3*parser.getMaxString(oldVerTxt); 4 Functionparser fparser1(size);Bei Zeile 4 geht er noch bis zum Konstruktor von "Parser", erstellt aber den buffer nicht und beendet das Programm.
-
Jetzt könntest du freundlicherweise den wert von size herausfinden, bevor das Programm beendet wird ...
-
Ach so ja, size=324.
-
1 int size; 2 Parser parser; 3 size=3*parser.getMaxString(oldVerTxt); 4 Functionparser fparser1(size);In Zeile 2 erstellst du ein Parser-Objekt mit dem Standardkonstruktor. Legst du denn in dem auch Speicher an für buffer? Falls nicht, dann darfst du nicht auf buffer zugreifen. Das heißt vor allem, dass getMaxString nicht auf buffer zugreifen darf.
-
getMaxString() ist nur eine Zählfunktion. Die greift nicht auf "buffer" zu. "buffer" wird erst mit dem Konstruktor "Parser(int size)" initialisiert. Bei Objekten die über den Default-Konstruktor erzeugt werden, wird "buffer" nicht benötigt.
-
getMaxString() ist eine Zählfunktion von was?
-
getMaxString() zählt die zusammenhängenden Zeichen in einer Textdatei aus. Dabei werden Leerzechen, Tabs und Newlines als "Lücken" interpretiert. Die eingelesen Zeichen werden nicht gespeichert, sondern nur gezählt.
-
GolanT schrieb:
getMaxString() ist nur eine Zählfunktion. Die greift nicht auf "buffer" zu. "buffer" wird erst mit dem Konstruktor "Parser(int size)" initialisiert. Bei Objekten die über den Default-Konstruktor erzeugt werden, wird "buffer" nicht benötigt.
Ich sehe hier nicht genug Informationen.
Wenn Du keinen Debugger zur Verfügung hast, der Dir sagt, warum das Programm aussteigt, schreib Printfs rein und zähle damit. Also 1, 2, 3, 4 usw ausgeben.
Wenn Du 1 und 2 ausgegeben wirst, weißt Du, dass der Fehler zwischen 2 und 3 liegt und verkleinerst die Abstände. Sobald Du die Funktion gefunden hast, die abschmiert, gehst Du da rein und machst das gleiche.Ist die Letzte Anweisung in einer Funktion ein printf und die erste nach dem Funktionsaufruf und das printf in der Funktion wird gerunfen, das printf nach der Funktion nicht, dann hast Du Dir in der Funktion den Stack zerschossen.
Prüfe also nach, ob Du beispielsweise über Arraygranzen hinausgegangen bist.
-
Okay, noch mal zum Anfang meiner Frage...
Ich weiß wo der Fehler liegt. Ich habe bereits mit Ausgaben gearbeitet und dabei festgestellt, dass das Programm immer wenn ein new Irgendwas[size], wobei size zur Laufzeit bestimmt wird, aufgerufen wird, einfach beendet wird. Es gibt keine Fehlermeldung bei der Ausführung. Das Programm hört einfach auf. Der Compiler ist mit dem Code zufrieden. Das Programm lief auch schon mal ohne Probleme. Erst seit dem ich die Klassen in Basisklassen und Ableitungen unterteilt habe, macht das Programm macken. Das es an dem new liegt weiß ich außerdem daher, das ich das erste Auftreten von new auskommentiert habe und das Programm dann beim nächsten new in einer ganz anderen Funktion beendet wurde.
Mein Problem ist jetzt, dass ich null Ahnung habe, warum er jetzt bei dem new-Operator zur Laufzeit (aber nicht beim compilieren) Probleme hat. Es muss wohl an der Vererbung liegen, ich weiß nur nicht warum. An der Arraygröße kann es auch nicht liegen, da es ja schon lief und die Größe aus Erfahrung nicht über 400 geht. Es wird auch vor der Initialisierung nie auf das Array zugegriffen.
-
Dann fang an dein Programm so weit auszukommentieren bis der Fehler nicht mehr kommt. Und zeig uns dann den kürzestmöglichen kompilierbaren Code bei dem der Fehler immer noch auftritt. Dann kann man vielleicht eher was sagen.
-
Das sind 10 Klassen + Sourcefiles. Was soll ich euch da schicken??? Kompilierbar ist das Programm ja auch. Es hört nur einfach auf. Wenn ich alle Zeilen, in denen ich ein Array mit new anlege auskommentiere ist das Programm eh nicht mehr lauffähig, da die Arrays ja benötigt werden.
Aber mal was anderes. Ich habe gerade ein Backup des Programms geladen, das lief... vorher... jetzt schmiert es auch ab, wenn zur Laufzeit Speicher angelegt werden soll. Ich hab langsam das Gefühl, dass es gar nicht am Programm liegt... Nur voran dann... Bin echt verzweifelt...
-
Ein Schuss ins Blaue: mach den Destruktor Parser::~Parser virtuell.
-
GolanT schrieb:
Okay, noch mal zum Anfang meiner Frage...
Ich weiß wo der Fehler liegt. Ich habe bereits mit Ausgaben gearbeitet und dabei festgestellt, dass das Programm immer wenn ein new Irgendwas[size], wobei size zur Laufzeit bestimmt wird, aufgerufen wird, einfach beendet wird. Es gibt keine Fehlermeldung bei der Ausführung.Welche Fehlermeldungen könnten denn überhaupt erwartet werden?
Einfach beendet kann viele Ursachen haben, dann kommt halt noch die Frage, welche Fehlermeldungen Dein OS dazu meldet.
Hast Du size im kritischen Moment mal ausgegeben?GolanT schrieb:
Das Programm hört einfach auf. Der Compiler ist mit dem Code zufrieden. Das Programm lief auch schon mal ohne Probleme.
Gleicher Compiler, gleiche Plattform?
Ist nachvollziehbar, was geändert wurde? (Existiert ein Repository?)GolanT schrieb:
Erst seit dem ich die Klassen in Basisklassen und Ableitungen unterteilt habe, macht das Programm macken. Das es an dem new liegt weiß ich außerdem daher, das ich das erste Auftreten von new auskommentiert habe und das Programm dann beim nächsten new in einer ganz anderen Funktion beendet wurde.
Wenn Du Dein Hauptprogramm auf den new-Aufruf beschränkst... was passiert?
GolanT schrieb:
Mein Problem ist jetzt, dass ich null Ahnung habe, warum er jetzt bei dem new-Operator zur Laufzeit (aber nicht beim compilieren) Probleme hat. Es muss wohl an der Vererbung liegen, ich weiß nur nicht warum. An der Arraygröße kann es auch nicht liegen, da es ja schon lief und die Größe aus Erfahrung nicht über 400 geht. Es wird auch vor der Initialisierung nie auf das Array zugegriffen.
Kann es sein, dass Du eine Exception erhältst, die Du nicht behandelst?
Ob Du virtuelle Destruktoren verwendest lohnt sich immer zu checken, aber an dem Fehler kann er eigentlich nicht schuld sein - außer Du rufst delete in einem Deiner Konstruktoren auf.
Bei 10 Klassen kann ich bei Bedarf mal drüber schauen, solltest Du den Fehler noch nicht gefunden haben.
-
GolanT schrieb:
Okay, noch mal zum Anfang meiner Frage...
Ich weiß wo der Fehler liegt. Ich habe bereits mit Ausgaben gearbeitet und dabei festgestellt, dass das Programm immer wenn ein new Irgendwas[size]...Ich hatte einen solchen Fehler schon ein paar Mal und es lag immer daran, das ein Speicherbereich überschrieben wurde, welcher nicht reserviert war... new quittiert Dir den Dienst, wobei dieser Fehler je nach Plattform (Win, Unix, Mac) unterschiedlich quittiert wird...
Suche mal nach "myString = new char[strlen(CopyString)+1]" - die "+1" ist extrem wichtig, weil sonst bei strcpy oder strcat trotzdem und unerlaubterweise eine "\0" angehängt wird und fertig ist Dein Pufferüberlauf.
-
Danke für die vielen Anregungen!
Ich denke nicht mehr, dass es am Programm liegt.
Das Programm soll zwei Dateien miteinander vergleichen (wie is erstmal egal) und hat in der Rohfassung (also ohne übersichtliche Klassenaufteilung) immer super funktioniert. Dabei habe ich zum Test immer die gleichen beiden Dateien genutzt.
Aus einem mir unerfindlichen Grund, will das Programm (auch in seiner Rohfassung) diese Dateien nicht mehr bearbeiten. Es öffnet sie und macht auch die ersten Anweisungen, aber sobald halt eine Stelle kommt, an der mittels new-Operator Speicher reserviert werden soll, springt das Programm raus. Nehme ich zwei andere Dateien (gleichen Typs) geht's wieder.
Falls dazu noch jemand eine Idee hat, immer her damit. Allen anderen vielen Dank für die Antworten.
-
schonmal versucht, irgendwelche exceptions zu fangen und auszugeben ?