Debug Assertion failed, Invalid Null pointer
-
Hallo!
Ich habe ein Programm in VS 10 geschrieben was so auch funktioniert. Wenn ich es in VS ausführe tut es alles was es soll.
Jetzt ist in der Aufgabenstellung aber darum gebeten worden, dass ich einen Dateiname beim Programmaufruf als Parameter übergebe. So dass ein Programmaufruf folgendermaßen aussieht:
<Programmname> <Dateiname>Also habe ich mein Programm entsprechend modifiziert. Alles klein Problem.
Das Problem kam dann erst als ich es auch in der Konsole und nicht in VS testen musste.
In der Konsole kam ein Fehler:Debug Assertation Failed!
[...]Goldberg_Tarjan_Algorithmus1.exe
File:[...]\include\xstring
Line: 930Expression: invalid null pointer
[...]
Ich kenne mich nicht besonders gut mit der Konsole aus daher hab ich vermutet dass der compiler von VS10 vielleicht keine Probleme sieht, aber gcc schon.
Also hab ich es mit Code::Blocks probiert da er mit gcc arbeitet. In Code::Blocks hat alles einwandfrei funktioniert. Dann habe ich später getestet ob die von Code::Blocks generierte .exe in der Konsole ausgeführt wird. Die funktioniert sogar!Was meint die Fehlermeldung mit Line 930? In meinem Programm hab ich keine 930 Zeilen. Kann mir jemand erklären was das Problem bedeutet und wie ich effektiver danach suchen kann?
Oder vielleicht sieht sogar jemand das Problem.
Ich lade mal nur die main hoch. Nach Bedarf schicke ich auch die zwei Klassen hinterher.Warum läuft die von Code::Blocks generierte .exe mit dem gleichen Code wie die von VS2010 generierte .exe aber die von VS gibt einen Fehler zurück?
Danke im Voraus

#include<iostream> #include<vector> #include<string> #include<fstream> #include<istream> #include<sstream> #include"Edge1.h" #include"Vertex.h" typedef vector<Edge1> Kanteninfo; using namespace std; int main(int argc, char* argv[]){ // ========= Variablendeklarationen int s,t; int Knotenanzahl, Kantenanzahl; string Quelldateiname; Kanteninfo E; // ========= -- // ============================================== Quelldateiname einlesen cout<<"Quelldatei: "; Quelldateiname = argv[1]; // ========= Datei öffnen ifstream Quelle; Quelle.open(Quelldateiname.c_str(), ios::binary|ios::in); if(!Quelle){ cerr << Quelldateiname << "Kann nicht geöffnet werden\n"; exit(-1); } // ======================================================================= // ============================================== Einlesen der Daten Quelle>>Knotenanzahl>>Kantenanzahl; Vertex *V = new Vertex[Knotenanzahl]; // Wie kann ich V per Referenz übergeben for(int i = 0; i < Kantenanzahl; i++){ int a,b,gew; Edge1 tmp; Quelle >> a >> b >> gew; // ließt Zeile aus tmp.set_Kante(i,a,b,gew); // beschreibt Kantenelement mit Zeile E.push_back(tmp); // beschreibt Kanteninformation mit gelesener Zeile in Form von Kantenelement V[a].push_Edge(i); // ergänzt den Knoten a (Startknoten) um die Kante mit Index i V[b].push_Backedge(i); // ergänzt den Knoten b (Endknoten) um die RückKante mit Index i } cout<<"Bitte geben sie s und t ein. In dieser Form:\ns t"<<endl; cin>>s>>t; V[s].set_Abstandsmarkierung(Knotenanzahl); // Psi(s) = n; // ======================================================================= // **************************************************************** // ============================================== Start Algorithmus // -- setzte f(e) := u(e) V e in +(s), f(e) = 0 sonst for(int i = 0, m = V[s].get_Kantenanzahl(); i < m; i++){ int currentedge = V[s].get_Edge(i); int b; int flow = E[currentedge].get_Kantengewicht(); E[currentedge].add_Flusswert(flow); // Flute die Kanten von s mit u(e) b = E[currentedge].get_Knotenb(); V[b].add_Excess(flow); // Addiere Überschuss auf // Da mit s begonnen wird, wird da kein Überschuss aufgehoben } bool Aktiver_Knoten = true; bool relable; while(Aktiver_Knoten){ // Solange noch aktive Knoten gefunden werden int aktiv, excess, rest; Aktiver_Knoten = false; relable = true; // Durchsuche Knoten nach AKTIVEN Knoten (außer s) for(int i = 0; i < Knotenanzahl; i++){ // FUNKTIONIERT 99%ig if(i != s && i != t){ if(V[i].get_Excess() > 0){ aktiv = i; // Aktiver Knoten = V[i] Aktiver_Knoten = true; // nächster Durchlauf aktiviert break; } } } // Falls v aktiv if(Aktiver_Knoten){ int Relableknoten = -1; int a,b, mf = V[aktiv].get_Rueckkanten(), m = V[aktiv].get_Kantenanzahl(), index; // ====================================== Vorwärtskanten - push for(int i = 0; i < m; i++){ // Durchsuche aktiven Knoten nach ERLAUBTER Kante in Gf index = V[aktiv].get_Edge(i); // Durchsuche zuerst Vorwärtskanten // Existiert Kante in Gf noch? if(E[index].get_Kantengewicht() - E[index].get_Flusswert() > 0){ b = E[index].get_Knotenb(); a = E[index].get_Knotena(); // Ist die Kante erlaubt? if(V[a].get_Abstandsmarkierung() == V[b].get_Abstandsmarkierung() + 1){ // -------------- dann push excess = V[a].get_Excess(); // Überschuss am Knoten rest = E[index].push(excess); // Verbleibender Überschuss nach dem pushen V[b].add_Excess(excess - rest); // Erhöht Überschuss an b um gepuschten wert V[a].replace_Excess(rest); // beschreibt den verbleibenden Überschuss neu relable = false; // Verhindert Relable und Durchsuchen der Rückkanten break; // (TESTLAUF -> Einfacher Algorithmus) || Wenn Knoten keinen Überschuss hat, dann suche neuen aktiven Knoten // Kann nur eine erlaubte Kante haben => Falls immernoch aktiv muss relabeln (Laufzeit) } else{ // Merke das Label der adjazenten Kante minimalen Abstands if(Relableknoten != -1){ if(V[a].get_Abstandsmarkierung() < V[Relableknoten].get_Abstandsmarkierung()){ Relableknoten = b; } } else Relableknoten = b; } } } // ====================================== Rückwärtskanten - push for(int i = 0; i < mf && relable; i++){ // Durchsuche aktiven Knoten nach ERLAUBTER Kante in Gf index = V[aktiv].get_Backedge(i); // Durchsuche jetzt Rückwärtskanten // Existiert überhaupt eine Rückkante? if(E[index].get_Flusswert() > 0){ a = E[index].get_Knotenb(); // Startknoten = Endknoten und andersrum, da b = E[index].get_Knotena(); // hiermit die Gegenläufige Kante gemeint ist. // Ist die Kante erlaubt? if(V[a].get_Abstandsmarkierung() == V[b].get_Abstandsmarkierung() + 1){ // -------------- Backpush excess = V[a].get_Excess(); rest = E[index].backpush(excess); V[b].add_Excess(excess - rest); V[a].replace_Excess(rest); relable = false; // Verhindert Relable break; // (TESTLAUF -> Einfacher Algorithmus) || Wenn Knoten keinen Überschuss hat, dann suche neuen aktiven Knoten // Kann nur eine erlaubte Kante haben => Falls immernoch aktiv muss relabeln (Laufzeit) } else{ // Merke das Label der adjazenten Kante minimalen Abstands falls relabelt wird if(Relableknoten != -1){ if(V[a].get_Abstandsmarkierung() < V[Relableknoten].get_Abstandsmarkierung()){ Relableknoten = b; } } else Relableknoten = b; } } } // ====================================== Relable - Es gab keine erlaubte Kante if(relable){ V[aktiv].set_Abstandsmarkierung(V[Relableknoten].get_Abstandsmarkierung()+1); } // ====================================== ?(Verbesserung -> direkter Push)? } } cout<<V[t].get_Excess()<<endl; for(int i = 0; i < Kantenanzahl; i++){ if(E[i].get_Flusswert() > 0) cout<<i<<" "<<E[i].get_Flusswert()<<endl; } return 0; }
-
also in zeile 24
Quelldateiname = argv[1];könnte es schon passieren, dass du ausserhalb eines arrays zugreifst. teste vorher lieber mal ob argc überhaupt grösser als 1 ist, ansonsten wäre da schon ein fehler (array indexe fangen bei 0 an und gehen bis GRÖSSE-1)
um das komplett zu verbessern mach folgendes:
int main(int argc, char * argv[]) { std::vector<std::string> parameters(argv, argv++argc); // hier sind jetzt alle parameter drin und wenn du falsch zugreifst sagt dir eigentlich sofort wer bescheid }die fehlermeldung bezieht sich nicht auf dein programm, also nicht direkt.der fehler kam in zeile 930 in datei xstring vor. die ist teil der STL. dass da fehler drin sind, ist sehr sehr sehr unwahrshceinlich. von daher hast du vorher shcon mindestens einen fehler gemacht, der aber erst spät(also in dieser datei) zum tragen kommt
zumal dein programm ein speicherloch ist. ich hab nicht genau drüber geguckt, aber an mindestens einer stelle machst du das hier:
Vertex * v = new Vertex[Knotenanzahl]; // aber ohne delete[] v; // am endehast du einen debugger? ja hast du, nämlich in vc++. geh dein programm mal schritt für schritt durch dann siehst du was du falsch machst. und einen stacktrace hast auch, wobei der dir hier nicht helfen wird
-
Du erfüllst die Laufzeitanforderungen der Aufgabenstellung an vielen Punkten nicht. Schau dir im ausgeteilten Skript an, wie du z.B. die aktiven Knoten verwaltest (steht im Laufzeitbeweis des Algorithmus).
-
Vielen Dank schonmal euch beiden. Das Delete hab ich eingefügt und über die Laufzeit mache ich mir im Moment Gedanken.