unbehandelte ausnahme

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Benutzeravatar
mulprogger
Beiträge: 16
Registriert: Do Apr 05, 2012 10:16 am

unbehandelte ausnahme

Beitrag von mulprogger » Mi Apr 11, 2012 10:04 am

Hallo!
Ich möchte folgende Fehlermeldung verstehen:

Unbehandelte Ausnahme bei 0x75a29673 in habitplanes.exe: Microsoft C++-Ausnahme: NEWMAT::ProgramException an Speicherposition 0x0033f2ab..

der Code befindet sich in der Datei newmat4.cpp die ich dem Project hinzugefügt habe.
Die Beschreibung der Datei: Constructors, ReSize, basic utilities
also die brauche ich auf jeden Fall, da ich die constructoren etc. verwende.

Code: Alles auswählen

bool Compare(const MatrixType& source, MatrixType& destination)
{
   if (!destination) { destination=source; return true; }
   if (destination==source) return true;
   if (!destination.DataLossOK && !(destination>=source))
      Throw(ProgramException("Illegal Conversion", source, destination));
   return false;
}
beim Debuggen weist mich visual Studio auf die Zeile mit "return false" hin.
Jetzt habe ich schon gefunden, dass ich den Fehler irgendwie mit try abfangen muss.
Kann mir bitte jemand erklären wie das genau funktioiert, bzw kann ich das throw auch so stehen lassen und den Fehler anders beheben?
lg

Edit by Xin: Codetags eingefügt

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: unbehandelte ausnahme

Beitrag von Xin » Mi Apr 11, 2012 10:13 am

mulprogger hat geschrieben:beim Debuggen weist mich visual Studio auf die Zeile mit "return false" hin.
Dann liegt der Fehler eine Zeile darüber und da steht ein sehr verdächtiges "Throw()", vermutlich ein Makro, dass throw aufruft.
mulprogger hat geschrieben:Jetzt habe ich schon gefunden, dass ich den Fehler irgendwie mit try abfangen muss.
Kann mir bitte jemand erklären wie das genau funktioiert, bzw kann ich das throw auch so stehen lassen und den Fehler anders beheben?

Code: Alles auswählen

try
{
  // Tu etwas, was eine Exception werfen könnte
}
catch( ProgramException const & pex )
{
  std::cout << "Hier kam eine Programmexception geflogen" << std::endl;
}
Er will eine Exception mit "Illegal Converseion" werfen.
Also stimmen die Vorbedinungen wohl nicht.

Das sieht mir nach einer etwas merkwürdigen Funktion aus, wenn "Compare" Zuweisungen auf "destination" macht...!?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
mulprogger
Beiträge: 16
Registriert: Do Apr 05, 2012 10:16 am

Re: unbehandelte ausnahme

Beitrag von mulprogger » Mi Apr 11, 2012 12:55 pm

Sehr richtig es ist ein Makro!
Ich werde aber nicht schlau warum er sich gerade bei diesem Throw = throw beschwert wenn sonst noch mehrere in der Datei stehen auch ohne try, catch....
Hier die Beschreibungen zum "exception handling" :

I have attempted to mimic the exception class structure in the C++ standard library, by defining the Logic_error and Runtime_error classes.

Suppose you have edited include.h to use my simulated exceptions or to disable exceptions. If there is no catch statement or exceptions are disabled then my Terminate() function in myexcept.h is called when you throw an exception. This prints out an error message, the dimensions and types of the matrices involved, the name of the routine detecting the exception, and any other information set by the Tracer class. Also see the section on error messages for additional notes on the messages generated by the exceptions.

You can also print this information in a catch clause by printing Exception::what().

If you are using compiler supported exceptions then see the section on catching exceptions.

See the file test_exc.cpp as an example of catching an exception and printing the error message.

The 08 version of newmat defined a member function void SetAction(int) to help customise the action when an exception is called. This has been deleted in the 09 and 10 versions. Now include an instruction such as cout << Exception::what() << endl; in the Catch or CatchAll block to determine the action.

The library includes the alternatives of using the inbuilt exceptions provided by a compiler, simulating exceptions, or disabling exceptions. See customising for selecting the correct exception option.

The rest of this section describes my partial simulation of exceptions for compilers which do not support C++ exceptions. I use Carlos Vidal's article in the September 1992 C Users Journal as a starting point.

Newmat does a partial clean up of memory following throwing an exception - see the next section. However, the present version will leave a little heap memory unrecovered under some circumstances. I would not expect this to be a major problem, but it is something that needs to be sorted out.

The functions/macros I define are Try, Throw, Catch, CatchAll and CatchAndThrow. Try, Throw, Catch and CatchAll correspond to try, throw, catch and catch(...) in the C++ standard. A list of Catch clauses must be terminated by either CatchAll or CatchAndThrow but not both. Throw takes an Exception as an argument or takes no argument (for passing on an exception). I do not have a version of Throw for specifying which exceptions a function might throw. Catch takes an exception class name as an argument; CatchAll and CatchAndThrow don't have any arguments. Try, Catch and CatchAll must be followed by blocks enclosed in curly brackets.

I have added another macro ReThrow to mean a rethrow, Throw(). This was necessary to enable the package to be compatible with both my exception package and C++ exceptions.

If you want to throw an exception, use a statement like

Throw(Exception("Error message\n"));
It is important to have the exception declaration in the Throw statement, rather than as a separate statement.

All exception classes must be derived from the class, Exception, defined in newmat and can contain only static variables. See the examples in newmat if you want to define additional exceptions.

Note that the simulation exception mechanism does not work if you define arrays of matrices.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: unbehandelte ausnahme

Beitrag von fat-lobyte » Mi Apr 11, 2012 1:07 pm

So, das war jetzt ein bisschen TMI.
Welche Library ist das? Irgendwie schaut die ziemlich alt aus, aus Zeiten in denen Exceptions von Compilern noch nicht gut unterstützt wurden.

Nachdem Exceptions eigentlich schon lange fix zur Sprache gehören, und diese Bibliothek anscheinend das richtige verhalten versucht nachzuahmen, würde ich dir empfehlen dich mit richtigen C++-Exceptions auseinaderzusetzen, und zwar nicht nur mit diesem Text.

Unsere wiki-Seite http://www.proggen.org/doku.php?id=cpp:exception:start für Exceptions ist noch recht dürftig, aber vielleicht findest du in Büchern oder anderen Webseiten noch material.
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
mulprogger
Beiträge: 16
Registriert: Do Apr 05, 2012 10:16 am

Re: unbehandelte ausnahme

Beitrag von mulprogger » Mi Apr 11, 2012 1:21 pm

Ok!
Ja in der Anleitung steht ja unter anderem, dass man einfach die c++ exceptions verwenden kann.
Das habe ich auch gemacht. Hier ist was u.a. in der include steht.

Code: Alles auswählen

//#define SimulateExceptions              // use simulated exceptions
#define UseExceptions                   // use C++ exceptions
//#define DisableExceptions               // do not use exceptions
Also jetzt sollte er die c++ exceptions verwenden.
Trotzdem habe ich an obiger Stelle einen uncaught exception error erhalten.
Nur aus neugierde wie verwebe ich angegebenen code mit try und catch?
unter try wird ja etwas ausgeführt. im code steht dafür aber if...

Code: Alles auswählen

bool Compare(const MatrixType& source, MatrixType& destination)
{
   if (!destination) { destination=source; return true; }
   if (destination==source) return true;
   if (!destination.DataLossOK && !(destination>=source))
      Throw(ProgramException("Illegal Conversion", source, destination));
   return false;
}

try
{
  // Tu etwas, was eine Exception werfen könnte
}
catch( ProgramException const & pex )
{
  std::cout << "Hier kam eine Programmexception geflogen" << std::endl;
}

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: unbehandelte ausnahme

Beitrag von cloidnerux » Mi Apr 11, 2012 1:35 pm

Also jetzt sollte er die c++ exceptions verwenden.
Trotzdem habe ich an obiger Stelle einen uncaught exception error erhalten.
Nur aus neugierde wie verwebe ich angegebenen code mit try und catch?
unter try wird ja etwas ausgeführt. im code steht dafür aber if...
Also, das System ist Folgendermaßen:
Innerhalb einer Fukntion, sei es eine Classemember.Funktion oder sonsteine, kannst du einen block mit try{} beginnen, auf dem dann catch(){} folgen muss, ähnlich wie bei schleifen oder ifs.
In dem try-Block steht der normale Code, der eben auch eine Exception werfen könnte. Dabei macht es keinen Unterschied ob eine Exception im try-Block oder in einer Funktion geworfen wird, die in dem try-Block ausgeführt wird. Sobald und auch NUR wenn eine Exception geworfen wird, wird aller nachfolgender Code nach dem werfen der Exception abgebrochen und zum zugehörigen catch gesprungen, um dort die Exception zu behandeln:

Code: Alles auswählen

void doSomething()
{
   //doSomething
   throw "Something bad happend";
}
...
void someFunction()
{
...
    try
    {
        doSomething();
        thisWillNeverHappen();
    }
    catch(string s)
    {
        cout << s << endl;
    }
    ...
}
Wichtig ist, das du mit catch entweder alles oder nur bestimmtest fangen kannst. Wenn du also generell catch(string s) schreibst, wird dieses catch nur aufgerufen wenn ein string mit throw geworfen wird und sonst nicht. Daher musst du dir immer sicherstellen, welche Datentypen die Objekte haben, die da geworfen werden.

Ich kann aber gerade keine Garantie geben, dass das so 100% richtig ist.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: unbehandelte ausnahme

Beitrag von fat-lobyte » Mi Apr 11, 2012 3:32 pm

Eine Exception (= Ausnahme) ist ein Objekt, das "geworfen" wird. Dieses Objekt hat, wie schon erwähnt einen Typ. Das kann ein std::exception sein, dein ProgramException, oder aber auch ein ganz normales "int", oder ein selbstdefinierter typ!

Wohin wird eine Exception geworfen? Die Exception "fliegt" solange, bis sie ein "catch"-Block auffängt, dabei fliegt sie auch den Funktionsaufruf-stack hoch.
Gibt es keinen "catch"-Block, ist die Exception unbehandelt (das wäre also dein Fehler!)

Das einfachste Beispiel ist folgendes:

Code: Alles auswählen

int main(int argc, char* argv[])
{
  throw 123;
  return 0;
}
Hier wird eine Exception vom typ "int" geworfen, und von niemandem Aufgefangen, also beendet sich das Programm mit "unhandled exception".

Du kannst es auch auffangen

Code: Alles auswählen

#include <iostream>

int main(int argc, char* argv[])
{
  bool alles_in_ordnung = false;
  try {
    if (!alles_in_ordnung)
      throw 123;
  }
  catch(int exc)
  {
    std::cerr<<"Ohje... Ein Fehler mit der Nummer "<<exc<<" ist aufgetreten. :-(\n";
  }
  return 0;
}
Wenn nicht alles_in_ordnung ist, wird die Exception geworfen und gleich wieder aufgefangen.

Bis jetzt war das alles nicht so nützlich. Jetzt kommt aber der echte Vorteil von Exceptions: du musst eine exception nicht in der gleichen Funktion auffangen, in der sie geworfen wurde! Du kannst sie auch in einer unterfunktion werfen, und ganz oben abfangen.

Code: Alles auswählen

#include <iostream>

class MeineBibliothekException {
};

void machwas()
{
  bool alles_in_ordnung = false;
  if (!alles_in_ordnung)
    throw MeineBibliothekException();
}

void meine_bibliothek()
{
    machwas();
}

int main()
{
  try {
    meine_bibliothek();
  }
  catch(const MeineBibliothekException&)
  {
    std::cerr<<"Ein Fehler ist aufgetreten.\n";
  }
  return 0;
}
Aufpassen musst du nur auf folgendes: wenn die Exception geworfen wird, wird das Programm quasi "Abgebrochen", und springt zum catch-Block. Natürlich wird auch der Code danach nicht mehr ausgeführt, es besteht die Gefahr von Speicherlecks oder nicht geschlossenen Dateien.

Das klingt jetzt schlimmer als es ist, denn in C++ packt man üblicherweise alle "sensiblen" ressourcen in eine Klasse, dessen Destruktor z.B. speicher löscht oder Dateien schließt. Dieses Prinzip nennt man RAII.
Wenn nämlich deine Exception durch die Gegend fliegt, werden alle Destruktoren der lokalen Variablen jedes Frames aufgerufen.
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
mulprogger
Beiträge: 16
Registriert: Do Apr 05, 2012 10:16 am

Re: unbehandelte ausnahme

Beitrag von mulprogger » Do Apr 12, 2012 8:57 am

Danke euch allen für eure Mühen!
Jetzt ist es mir klarer

Antworten