Hallo, On Sat, 27 Dec 2003 at 19:33 (+0100), Andre Heine wrote:
Am Saturday 27 December 2003 14:25 schrieb Bernhard Walle:
On Sat, 27 Dec 2003 at 14:10 (+0100), Andre Heine wrote:
Am Saturday 27 December 2003 13:42 schrieb Bernhard Walle:
[...]
uninitialisierte Objekte kann man in Java nicht zugreifen, da sowas bereits der Compiler überprüft.
Nun, ein "int" ist auch kein Objekt!
Stimmt, macht aber nichts.
Bsp.:
// j hat irgendeinen Wert int i; if (j > 5) { i = 10; } System.out.println(i); // wird vom Compiler abgelehnt da potentiell // uninitialisiert
Wenn Du nun aber z.B. ein String-Objekt hast und diesen String mit etwas vergleichen möchtest.
public class test { public static void main( String argv[] ){ // Dieser Code ist SUPERSCHLAMPIG und ein negativ Beispiel argv[1].equals("compse"); } }
Kann er ja nicht. Woher soll er denn wissen, wie lang argv ist? Und hier wird auch keine NullPointerException sondern eine ArrayIndexOutOfBoundsException kommen.
Hier meckert der Compiler definitiv nicht beim kompilieren!
voodoo@yamato:~/java$ java test Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 at test.main(test.java:18)
Sag ich doch.
Hier ist mein Programm Hardcore ausgestiegen, würde ich die Exception fangen, läuft das Programm eben weiter.
Richtig.
Auch wenn hier etwas sehr undefiniertes passiert ist...
Nein, sehr undefiniert ist das nicht. In Java ist ein Array ein Objekt, genauso wie in C++ ein std::vector. In Java wird jeder Arrayzugriff vorher überprüft und notfalls eine ArrayIndexOutOfBoundsException geworfen. Keine Kunst, weil ja String[] ein Objekt ist und kein Zeiger auf irgendwas wie klassische C-Arrays. Bei einem std::vector kannst Du auch statt des Indexoperators die at()-Methode verwenden, welche Indexzugriffe genauso überprüft und notfalls eine std::out_of_range Ausnahme wirft.
Das ist nach meiner Meinung ein Speicherzugrifffehler, weil ich auf ein Array Element zugreife das nicht existiert, bzw. der Bereich mir nicht gehört.
Nein. Auf den Speicher wird nicht zugegriffen. Java merkt sich intern die Größe des Arrays (deshalb gibt es ein args.length) und vergleich halt bei jedem Zugriff, ob Du Dich innerhalb der Schranken befindest. Bei Rattis Problem geht es um einen SIGSEGV. Da wird über Perl auf C-Code zugegriffen und dieser Code produziert einen echten Speicher- zugriffsfehler. Das Betriebssystem schickt an den Prozess ein SIGSEGV Signal mit der Aufforderung, dass das Programm beendet wird.
Ein Nullzeiger ist kein uninitialisiertes Objekt. Es exisitert überhaupt kein Objekt, die Referenzvariable hat schlicht den Wert
Wenn das Objekt nicht existiert, darf ich auch nicht darauf zugreifen, d.h. ich habe auf Speicher zugegriffen, der sonstwem gehört.
Ist diese Annahme falsch?
Ja. Der Zeiger (die Referenz) zeigt ja nicht irgendwohin auf Speicher, dem keiner gehört sondern er hat den Wert null. Bei jeder Indirektion (Methodenaufruf, Elementzugriff) wird von der JVM geprüft, ob es sich um einen null-Zeiger handelt. Wenn ja, dann wird eine NullPointerException geworfen, bevor es zu dem Zugriff überhaupt kommt, d. h. bevor das Betriebssystem was davon mitbekommen würde.
In C++ greift man auf einen Speicherbereich zu, der vom Betriebssystem einem anderen Prozess zugeordnet wurde. Dies wird dann vom Betriebs- system mit einem SIGSEGV abgelehnt. Das Programm befindet sich dadurch in einem potentiell undefinierten Zustand, kann noch Aufräumarbeiten durchführen und hat sich dann zu beenden. Standardmäßig beendet es sich umgehend. Eine Ausnahme wird da an keiner Stelle geworfen.
In meinem C++ Buch steht wofür ich das "exception handling" nutzen kann.
Zitat aus "C++ Einführung in die professionelle Programmierung", von Breymann, Hanser Verlag.
- Division durch Null - Bereichsüberschreitung eines Arrays - Syntaxfehler bei Eingaben - Zugriffe auf nicht geöffnete Dateien - Fehlschlag bei der Speicherbeschaffung - Nichteinhaltung einer Vorbedingung einer Methode
Ist den ein "Fehlschlag bei der Speicherbeschaffung" kein falscher Zugriff auf den Speicher (oder ist damit nur gemeint, das zuwenig Speicher vorhanden ist, vermutlich ja *g*).
Nein. Der new-Operator kann scheitern, wenn kein Speicher mehr da ist. Dann wirft dieser Operator eine std::bad_alloc-Ausnahme. Wenn Du die Ausnahme abfängst und trotzdem weitermachst und auf den nicht beschafften Speicher zugreifst, bekommst Du wieder einen SIGSEGV, den Du nicht mehr abfangen kannst (außer über Signal handling). Gruß, Bernhard -- _________ http://www.bwalle.de _________________________________________________ Win95 is not a virus; a virus does something.