hi folkz ich hab mal eine frage zu objecten in c++ und zwar habe ich folgenden code: main.h: using namespace std; class test { public: test(); ~test(); void say(string toSay); }; main.cpp: #include <iostream> #include <string> #include "main.h" using namespace std; test::test() { cout << "test erstellt\n"; } test::~test() { cout << this << " test getoetet\n"; } void test::say(string toSay) { cout << toSay; } int main() { test Test = test(); Test.~test(); cout << "noch ist es nicht zu ende\n"; Test.say("fehler\n"); return 0; } lasse ich das programm laufen erhalte ich folgende ausgabe: test erstellt 0xbfa25ffb test getoetet noch ist es nicht zu ende fehler 0xbfa25ffb test getoetet änder ich die main folgendermaßen ab: int main() { test Test = test(); delete &Test; cout << "noch ist es nicht zu ende\n"; Test.say("fehler\n"); return 0; } sieht die ausgabe so aus: test erstellt 0xbffde59b test getoetet *** glibc detected *** free(): invalid pointer: 0xbffde59b *** WARUM ?? wenn ich das richtig verstanden habe, gibt delete &Test doch den speicherplatz von Test wieder frei, warum kommt es dann zu einer Fehlermeldung, bevor "noch ist es nicht zu ende" angezeigt wird ?? und anderseits im ersten fall das object zwei mal zerstört bzw, warum kann ich auf eine methode von Test zugreifen, obwohl es schon wieder freigegeben wurde ?? greatz Johannes -- Es gibt 10 Arten von Menschen auf dieser Welt, die einen verstehen das Binärsystem und die anderen verstehen es nicht.
Am Mittwoch, 16. November 2005 23:06 schrieb Frank Lanitz:
'n Abend!
Am Mittwoch 16 November 2005 22:50 schrieb Johanns Schneider:
int main() { test Test = test(); delete &Test;
Schuss ins Blaue. Sollte vor einem delete nicht ein new stehen oder täausche ich mich da?
Genau, Test wird auf dem Stack angelegt. test *Test = new test; So landet's auf dem Heap und kann hinterher mit delete Test; gekillt werden. Auch ruft man niemals explizit den Destruktor auf, das ist "pfui"! Grüsse aus Meissen Jörg
Am Mittwoch, 16. November 2005 22:50 schrieb Johanns Schneider: ja, das mit dem new delete stimm schonmal.
int main() { test Test = test(); Test.~test(); cout << "noch ist es nicht zu ende\n"; Test.say("fehler\n"); return 0; }
Hier wird nur der Destruktor aufgerufen, der aber das Objekt nicht explizit zerstört. Hast das ja am 2. Beispiel gesehen das das gar nicht erlaubt ist. Ausserdem triggert der Destruktor doch nicht das zerstören des Objekts, sondern wird von eben diesem ausgelöst oder sollte ich mich irren? Ansonsten ist der ja nix weiter als ne Memberfunktion. Wenn ich jetzt richtig informiert bin wird ein test Test doch automatisch auf dem Stack erstellt, ein test *Test dagegen nach der initialisierung mit new() im Freispeicher (Heap) bereitgestellt. Die lokale Variable wird wieder gelöscht, sobald man ihren Gültigkeitsbereich verlässt. Und auf diesen Speicherbereich wird delete wohl keine Zugriffsrechte haben, darum der Speicherzugriffsfehler. test *Test = new test(); delete Test; cout << "noch ist es nicht zu ende\n"; Test->say("fehler\n"); wird zwar so auch funktionieren, ist allerdings sehr gefährlich. Denn der Speicher ist ja nicht mehr reserviert. Es funktioniert hier nur, weil noch keine andere Variable sich diesen Speicherbereich geschnappt hat (und delete die instanzen ja nicht auf 0 setzt) daher sieht man ja häufig sowas: delete Test; Test = NULL; um ungewollten zugriff auf das Objekt sofort feststellen zu können.
Am Donnerstag, 17. November 2005 02:33 schrieb Andre Rudlaff:
test *Test = new test(); delete Test; cout << "noch ist es nicht zu ende\n"; Test->say("fehler\n");
Krawumm, das Objekt und sein Speicher existieren nicht mehr.
wird zwar so auch funktionieren, ist allerdings sehr gefährlich. Denn der Speicher ist ja nicht mehr reserviert. Es funktioniert hier nur, weil noch keine andere Variable sich diesen Speicherbereich geschnappt hat (und delete die instanzen ja nicht auf 0 setzt)
Der Speicher kann auch von einem anderen x-beliebigen Prozess belegt worden sein. Der übliche Weg ist eigentlich, ein Objekt erst dann zu terminieren, wenn man es definitiv nicht mehr benötigt.
daher sieht man ja häufig sowas:
delete Test; Test = NULL;
um ungewollten zugriff auf das Objekt sofort feststellen zu können.
Das sollte eigentlich sofort knallen, Du schreibst schließlich auf eine Adresse, die Dir nicht mehr gehört. Wenn Du einen Speicherbereich nullen willst, wofür auch immer, musst Du ihn erst NULLen und dann deleten. Grüsse aus Meissen Jörg
Jörg Pauly wrote:
Am Donnerstag, 17. November 2005 02:33 schrieb Andre Rudlaff:
test *Test = new test(); delete Test; cout << "noch ist es nicht zu ende\n"; Test->say("fehler\n");
Krawumm, das Objekt und sein Speicher existieren nicht mehr.
wird zwar so auch funktionieren, ist allerdings sehr gefährlich. Denn der Speicher ist ja nicht mehr reserviert. Es funktioniert hier nur, weil noch keine andere Variable sich diesen Speicherbereich geschnappt hat (und delete die instanzen ja nicht auf 0 setzt)
Der Speicher kann auch von einem anderen x-beliebigen Prozess belegt worden sein. Der übliche Weg ist eigentlich, ein Objekt erst dann zu terminieren, wenn man es definitiv nicht mehr benötigt.
daher sieht man ja häufig sowas:
delete Test; Test = NULL;
um ungewollten zugriff auf das Objekt sofort feststellen zu können.
Das sollte eigentlich sofort knallen, Du schreibst schließlich auf eine Adresse, die Dir nicht mehr gehört. Wenn Du einen Speicherbereich nullen willst, wofür auch immer, musst Du ihn erst NULLen und dann deleten.
Grüsse aus Meissen Jörg
alao wenn ich das jetzt richtig verstanden habe ist es so besser (richtig?): test *Test = new test(); Test = NULL; delete Test; cout << "noch ist es nicht zu ende\n"; Test->say("fehler\n"); return 0; aber warum lautet meine ausgabe nun test erstellt noch ist es nicht zu ende fehler ?? ich greife doch nachdem ich das object getötet habe und der speicher genullt wurde auf eine methode des objectes zu. Und warum wird die meldung des dekonstuctors nicht mehr angezeigt ?? fragen über fragen ....MFG Johannes -- Es gibt 10 Arten von Menschen auf dieser Welt, die einen verstehen das Binärsystem und die anderen verstehen es nicht.
Am Donnerstag 17 November 2005 09:23 schrieb Johanns Schneider:
Jörg Pauly wrote:
Wenn Du einen Speicherbereich nullen willst, wofür auch immer, musst Du ihn erst NULLen und dann deleten.
Besser andersherum....
Grüsse aus Meissen Jörg
alao wenn ich das jetzt richtig verstanden habe ist es so besser (richtig?):
test *Test = new test(); Test = NULL; delete Test;
Du versuchst etwa zu löschen, auf das ein NULL-Zeiger weist. Da sich Dein Objekt wahrscheinlich nicht auf 0x0 befindet, na ich weiss nicht.... Sollte das eigentlich nicht mit einem Segfault beantwortet werden? *dumm in die Runde frag* -- Wie man sein Kind nicht nennen sollte: Dick S. Ding -- Nur wer seinen eigenen Weg geht, kann vom niemandem überholt werden. -- Marlon Brando
Am Donnerstag, 17. November 2005 09:45 schrieb Frank Lanitz:
Am Donnerstag 17 November 2005 09:23 schrieb Johanns Schneider:
Jörg Pauly wrote:
Wenn Du einen Speicherbereich nullen willst, wofür auch immer, musst Du ihn erst NULLen und dann deleten.
Besser andersherum....
Grüsse aus Meissen Jörg
alao wenn ich das jetzt richtig verstanden habe ist es so besser (richtig?):
test *Test = new test(); Test = NULL; delete Test;
Du versuchst etwa zu löschen, auf das ein NULL-Zeiger weist. Da sich Dein Objekt wahrscheinlich nicht auf 0x0 befindet, na ich weiss nicht....
Sollte das eigentlich nicht mit einem Segfault beantwortet werden? *dumm in die Runde frag*
Stimmt, Du hast Recht, man will ja üblicherweise nicht den Zeiger, sondern dessen Speicher löschen: test *Test = new test; *Test = NULL; // Das nullt den Speicher des Objektes delete Test; Was man auf keinen Fall tun sollte, ist auf ein deletetes Objekt zuzugreifen. Der Kernel kann Millisekunden nach dem delete-Aufruf den Speicher neu zugeteilt haben, und dann gibt's unter Garantie einen SegFault. Auf einen auf NULL gesetzten Zeiger zuzugreifen ist auch "bah", endet auch mit einem SegFault, aber wohl nur bei Schreibzugriff. Sorry, mein Fehler... :-( Grüsse aus Meissen Jörg
Jörg Pauly wrote:
test *Test = new test; *Test = NULL; // Das nullt den Speicher des Objektes delete Test;
Was man auf keinen Fall tun sollte, ist auf ein deletetes Objekt zuzugreifen. Der Kernel kann Millisekunden nach dem delete-Aufruf den Speicher neu zugeteilt haben, und dann gibt's unter Garantie einen SegFault.
Grüsse aus Meissen Jörg
wenn ich das wie oben mache bekomme ich immer folgende fehlermeldungen: main.cpp:25: error: no match for 'operator=' in '* Test = 0' main.h:4: note: candidates are: test& test::operator=(const test&) und den fehler wollt ich eigentlich nur zum lernen einbauen, um genau das zu verstehen, was ihr mir grade erklärt ;) greatz Johannes -- Es gibt 10 Arten von Menschen auf dieser Welt, die einen verstehen das Binärsystem und die anderen verstehen es nicht.
*Test = NULL; // Das nullt den Speicher des Objektes
Um das zu machen müsstest Du den =operator überladen, da Du auf ein dereferenziertes Objekt zugreifst. Warum willst Du den Speicher 'nullen', das bringt doch nichts. Wenn Du ein delete aufgerufen hast, ist der Bereich doch wieder freigegeben (nicht ge'nullt') und der Prozess kann ihn wieder neu allokieren. Grüße Alex
Am Donnerstag, 17. November 2005 11:29 begab es sich, daß Alexander Muthler folgendes in den Rechenknecht kloppte:
*Test = NULL; // Das nullt den Speicher des Objektes
Um das zu machen müsstest Du den =operator überladen, da Du auf ein dereferenziertes Objekt zugreifst. Warum willst Du den Speicher 'nullen', das bringt doch nichts. Wenn Du ein delete aufgerufen hast, ist der Bereich doch wieder freigegeben (nicht ge'nullt') und der Prozess kann ihn wieder neu allokieren.
Zugegeben, das ganze ist ziemlich hypothetisch; wenn ich ein Objekt deleted habe, interessiert es mich sowieso nicht mehr. Einzig sinnvoll ist in unübersichtlichen Codestücken den Zeiger zu nullen, damit man ihn testen kann. Aber auch das spar ich mir meistens. --- Grüsse aus Meissen Jörg Pauly
da habt ihr wohl verständnisschwierigkeiten.
*Test = NULL; // Das nullt den Speicher des Objektes
nullt ja nicht den speicher des objektes, sondern den zeiger. und das war offensichtlich auch gemeint. der kommentar ist da nur falsch formuliert. man nullt den zeiger nach jedem delete, um daran indirekt sehen zu können, ob der zeiger auf noch referenzierten speicher zeigt. wird von vielen als debug-hilfe benutzt. ausserdem ist ein delete auf ein null-zeiger im gegensatz auf eine andere adresse mit bereits freigegeben speicher okay. trotzdem ist das problem auch damit nicht wirklich gelöst. nullen des speicherbereichs ist natürlich in den absolut meisten fällen quatsch. Jörg Pauly wrote:
Am Donnerstag, 17. November 2005 11:29 begab es sich, daß Alexander Muthler folgendes in den Rechenknecht kloppte:
*Test = NULL; // Das nullt den Speicher des Objektes
Um das zu machen müsstest Du den =operator überladen, da Du auf ein dereferenziertes Objekt zugreifst. Warum willst Du den Speicher 'nullen', das bringt doch nichts. Wenn Du ein delete aufgerufen hast, ist der Bereich doch wieder freigegeben (nicht ge'nullt') und der Prozess kann ihn wieder neu allokieren.
Zugegeben, das ganze ist ziemlich hypothetisch; wenn ich ein Objekt deleted habe, interessiert es mich sowieso nicht mehr. Einzig sinnvoll ist in unübersichtlichen Codestücken den Zeiger zu nullen, damit man ihn testen kann. Aber auch das spar ich mir meistens.
--- Grüsse aus Meissen Jörg Pauly
Am Freitag, 18. November 2005 14:42 begab es sich, daß adsci folgendes in den Rechenknecht kloppte:
da habt ihr wohl verständnisschwierigkeiten.
*Test = NULL; // Das nullt den Speicher des Objektes
nullt ja nicht den speicher des objektes, sondern den zeiger. und das war offensichtlich auch gemeint. der kommentar ist da nur falsch formuliert.
Einspruch. Test ist also ein Pointer auf ein Objekt. Dann ergibt Test = NULL;, daß der Pointer auf Null gesetzt wird. Rufe ich aber *Test = NULL auf, dann geht es direkt auf's Objekt. Dafür müsste, wie Alexander völlig richtig sagte, der =-Operator überladen sein, ansonsten weist der Compiler das sowieso zurück.
man nullt den zeiger nach jedem delete, um daran indirekt sehen zu können, ob der zeiger auf noch referenzierten speicher zeigt. wird von vielen als debug-hilfe benutzt. ausserdem ist ein delete auf ein null-zeiger im gegensatz auf eine andere adresse mit bereits freigegeben speicher okay.
trotzdem ist das problem auch damit nicht wirklich gelöst.
Das Problem tritt IMHO eh nur in der Theorie auf. Auf freigegebenen Speicher zuzugreifen führt über kurz oder lang zum SegFault, da braucht im System nur der Speicher mal knapp werden.
nullen des speicherbereichs ist natürlich in den absolut meisten fällen quatsch.
Eigentlich immer, da kann man das System einfach seine Arbeit tun lassen. --- Grüsse aus Meissen Jörg Pauly
oh, du hast natürlich recht :-) hab dezent das * übersehen! gruß marcel Jörg Pauly wrote:
Am Freitag, 18. November 2005 14:42 begab es sich, daß adsci folgendes in den Rechenknecht kloppte:
da habt ihr wohl verständnisschwierigkeiten.
*Test = NULL; // Das nullt den Speicher des Objektes
nullt ja nicht den speicher des objektes, sondern den zeiger. und das war offensichtlich auch gemeint. der kommentar ist da nur falsch formuliert.
Einspruch. Test ist also ein Pointer auf ein Objekt. Dann ergibt Test = NULL;, daß der Pointer auf Null gesetzt wird. Rufe ich aber *Test = NULL auf, dann geht es direkt auf's Objekt. Dafür müsste, wie Alexander völlig richtig sagte, der =-Operator überladen sein, ansonsten weist der Compiler das sowieso zurück.
man nullt den zeiger nach jedem delete, um daran indirekt sehen zu können, ob der zeiger auf noch referenzierten speicher zeigt. wird von vielen als debug-hilfe benutzt. ausserdem ist ein delete auf ein null-zeiger im gegensatz auf eine andere adresse mit bereits freigegeben speicher okay.
trotzdem ist das problem auch damit nicht wirklich gelöst.
Das Problem tritt IMHO eh nur in der Theorie auf. Auf freigegebenen Speicher zuzugreifen führt über kurz oder lang zum SegFault, da braucht im System nur der Speicher mal knapp werden.
nullen des speicherbereichs ist natürlich in den absolut meisten fällen quatsch.
Eigentlich immer, da kann man das System einfach seine Arbeit tun lassen.
--- Grüsse aus Meissen Jörg Pauly
Moin, adsci schrieb am 18.11.2005 14:42:
da habt ihr wohl verständnisschwierigkeiten.
*Test = NULL; // Das nullt den Speicher des Objektes
nullt ja nicht den speicher des objektes, sondern den zeiger.
Ähem, und was macht dann das? Test = 0; Ich sehe das so: 'Test' ist der Zeiger auf einen Speicherbereich im Heap. Also setzt 'Test = 0' diesen Zeiger auf 0, wodurch der versehentliche Zugriff auf das Objekt an Adresse '*Test' nicht mehr möglich ist und ein Test '(!Test)' einfach möglich ist. '*Test' ist der dereferenzierte Zeiger, womit man direkt auf das Objekt zugreift, das an Adresse 'Test' beginnt. Ja, was soll dann bloß '*Test = NULL' bedeuten (wenn '=' nicht überladen wurde)?
man nullt den zeiger nach jedem delete, um daran indirekt sehen zu können, ob der zeiger auf noch referenzierten speicher zeigt.
Genau, aber der Zeiger ist 'Test' und nicht '*Test'. Michael
Sorry, für das überflüssige Posting. Jörg Pauly hat ja schon alles richtig gestellt. Ich konnte einfach nicht mit der Antwort warten, bis ich Jörgs Posting gelesen hatte :) Michael
Am Freitag, 18. November 2005 15:55 begab es sich, daß Michael Wenger folgendes in den Rechenknecht kloppte:
Sorry, für das überflüssige Posting. Jörg Pauly hat ja schon alles richtig gestellt.
Überflüssig? Nein, gewiss nicht, das ist ja hier kein Chat. Aber mir fällt gerade eine von mir gerne genutzte reale Anwendung ein, bei der ich dereferenziert nulle: Ich habe die (dumme) Angewohnheit, alle wichtigen Variabelen bei der Konstruktion eines Objektes zu initialisieren. Ist dann da z.B. ein QString* dabei, dann mache ich oft dies hier: m_myString = new QString; *m_myString = NULL; Das Resultat ist ein leerer String. Klar, das ginge auch mit m_myString = new QString(''); Aber jeder hat ja so seine Vorlieben.... ;-) --- Grüsse aus Meissen Jörg Pauly
On Saturday 19 November 2005 01:22, Jörg Pauly wrote: Hi, Obwohl ich mich anfangs nicht in diese disskussion einmnischen wollte, muss ich nun doch noch meinen senf dazugeben: 1:) Objektinizialiseirung: Ein objekt nach seiner instanzierung noch mit einem "default" Wert zu initialisieren, ist in einer objektorientierten Sprache absolut ueberfluessig. Dazu gibt es Konstruktoren. Falls einer solchen Code oder sogar Klassen schreibt welche eine solche Initialisierung notwendig machen, hat einen grundlegenden Gedanken der objektorientierten Programierung noch nicht richtig verstanden. Er heist Kapselung. 2:) Speicher zu nullen: Speicher eines objektes zu nullen ist in 99.9% aller Faelle ebenfals ueberfluessig. Es ist dort notwendig, wo objekte entschluesselte daten oder passwoerter enthalten. Geloescht wird solcher Speicher dann allerdings nicht einfach durch zuweisung einer NULL an ein objekt, sondern es muss der ganze belegte Speicherbereich geloescht werden. Die groesse seines Speicherbereichs liefert sizeof(..); Nebenbei: Enhalten Objekte wirklich solche Daten, wird der Speicher sowieso nicht vom normal Heap genommen, sondern Pageweise allokiert und gepinnt, da er dann nicht auf die Platte ausgelagert werden darf. Dazu gibt es aber Bibliotheken. 3:) Zeiger zu ueberpruefen. Zeiger direkt zu verwenden ist schon fahrlaessig, diesen dann aber nicht noch vor dedem benutzen auf NULL zu ueberpruefen, vorsaetzlich, eine solche Person hat noch niemals einen Programmabsturz auf einer Plattform suchen muessen wo es weder einer Stackdump noch debugger gibt. Wenn Zeiger verwenden werden muessen, dann IMMER mit "smart pointers". Wer das beherzigt, produziert auch weniger Speicherlecks. Guckst du hier www.boost.org Ansonsten viel Spass beim Programmieren! Markus
Am Freitag, 18. November 2005 15:55 begab es sich, daß Michael Wenger
folgendes in den Rechenknecht kloppte:
Sorry, für das überflüssige Posting. Jörg Pauly hat ja schon alles richtig gestellt.
Überflüssig? Nein, gewiss nicht, das ist ja hier kein Chat.
Aber mir fällt gerade eine von mir gerne genutzte reale Anwendung ein, bei der ich dereferenziert nulle:
Ich habe die (dumme) Angewohnheit, alle wichtigen Variabelen bei der Konstruktion eines Objektes zu initialisieren. Ist dann da z.B. ein QString* dabei, dann mache ich oft dies hier:
m_myString = new QString; *m_myString = NULL;
Das Resultat ist ein leerer String. Klar, das ginge auch mit
m_myString = new QString('');
Aber jeder hat ja so seine Vorlieben.... ;-)
--- Grüsse aus Meissen Jörg Pauly
-- There is a Massachusetts law requiring all dogs to have their hind legs tied during the month of April.
hi folkz, ich hab ein problem mit meinem glade (Glade 2.10.0). ich kann keine c++ projekter erstellen. Ich bekomme immer die fehlermeldung glade-- nicht gefunden. Googeln hat bei mir nur ein rpm für suse 8.x hervorgebracht. Wo gibt es welche für suse 10 ?? greatz Johannes -- Es gibt 10 Arten von Menschen auf dieser Welt, die einen verstehen das Binärsystem und die anderen verstehen es nicht.
Am 17 Nov 2005 um 9:45 hat Frank Lanitz geschrieben:
Am Donnerstag 17 November 2005 09:23 schrieb Johanns Schneider:
Jörg Pauly wrote:
Wenn Du einen Speicherbereich nullen willst, wofür auch immer, musst Du ihn erst NULLen und dann deleten.
Besser andersherum....
Grüsse aus Meissen Jörg
alao wenn ich das jetzt richtig verstanden habe ist es so besser (richtig?):
test *Test = new test(); Test = NULL; delete Test;1
Du versuchst etwa zu löschen, auf das ein NULL-Zeiger weist. Da sich Dein Objekt wahrscheinlich nicht auf 0x0 befindet, na ich weiss nicht....
Sollte das eigentlich nicht mit einem Segfault beantwortet werden? *dumm in die Runde frag*
Nein. Einen Null Pointer kann so oft gelöscht werden wie man will. Es passiert nichts. Denn der delete operator prüft, ob der Zeiger NULL ist. Wenn ja, tut er nichts. Aber um sicher zu sein, dass ein Objekt gelöscht ist, sollte man am besten den Speicherbereich mit einem Bytemuster belegen. Aka delete operator überschreiben. Dann passiert wirklich ein Segfault, wenn ein gelöschtes Objekt verwendet wird. (vtable zeigt auf Adressen mit dem Bytemuster. Bei mir 0xBDBDBDBD) Dies ist in gewisser weise gut um diese Zugriffe auf gelöschte Objekte festzustellen. Test* t = new Test(); t->tuwas("bla"); delete t; t->tunichts("pfui"); Gruß, Lothar
-- Wie man sein Kind nicht nennen sollte: Dick S. Ding
-- Nur wer seinen eigenen Weg geht, kann vom niemandem überholt werden. -- Marlon Brando
-- Um die Liste abzubestellen, schicken Sie eine Mail an: suse-programming-unsubscribe@suse.com Um eine Liste aller verfügbaren Kommandos zu bekommen, schicken Sie eine Mail an: suse-programming-help@suse.com
-- Lothar Behrens | Rapid Prototyping ... Rosmarinstr 3 | 40235 Düsseldorf | www.lollisoft.de
Am Donnerstag 17 November 2005 10:31 schrieb lothar.behrens@lollisoft.de:
Am 17 Nov 2005 um 9:45 hat Frank Lanitz geschrieben:
Sollte das eigentlich nicht mit einem Segfault beantwortet werden? *dumm in die Runde frag*
Nein.
Einen Null Pointer kann so oft gelöscht werden wie man will. Es passiert nichts. Denn der delete operator prüft, ob der Zeiger NULL ist. Wenn ja, tut er nichts.
Gut zu wissen ;)
Aber um sicher zu sein, dass ein Objekt gelöscht ist, sollte man am besten den Speicherbereich mit einem Bytemuster belegen. Aka delete operator überschreiben.
Na ich weiß nicht. Eine Idee ist das schon. Die Auswirkungen auf die Performance würde mich da einmal interessieren. Gruss Frank -- Hoffnung ist ein gutes Frühstück, aber ein schlechtes Abendbrot. -- Francis Bacon
On 17.11.2005 07:15, Jörg Pauly wrote:
delete Test; Test = NULL;
Das sollte eigentlich sofort knallen, Du schreibst schließlich auf eine Adresse, die Dir nicht mehr gehört.
Nein, "Test" ist ein Zeiger auf einen Speicherbereich. Dieser Speicherbereich (nicht der Zeiger!) wurde gerade mit delete gelöscht. Der Zeiger kann ohne weiteres auf 0 (oder wenn's sein muss auch NULL) gestzt werden. Wenn man das konsequent durchzieht, vereinfacht dies im späteren Verlauf des Programmes die Abfrage, ob das Objekt existiert: if( Test ) { Test->say("..."); } else { cout << "Objekt Test nicht angelegt!" << endl; } oder so in der Richtung... Grüße, -oli- (Oliver Baum)
Hi Liste, hier wahrscheinlich eine ganz simple Frage fuer eingefleischte Java Programmierer: Ich will eine Variable ueber System.out.println(a) ausdrucken. a ist vom Type "long" und hat einen Wert von zB 1,234,567,890 (die Kommas sind nur fuer die bessere Lesbarkeit hier geschrieben worden). Wenn ich nun "a" "drucken" will, erhalte ich 1.2e10, also im "scientific" Format. Wie schaffe ich es, dass ich aber einen Ausgabe bekomme, die 1234567890 resp. 1234567890,00 bekomme. Wie muss also der Befehl lauten, um die Zahl als ganzes auszugeben? Herzlichen Dank fuer Eure Unterstuetzung, Chris
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hallo,
Christoph Merk
hier wahrscheinlich eine ganz simple Frage fuer eingefleischte Java Programmierer: Ich will eine Variable ueber System.out.println(a) ausdrucken. a ist vom Type "long" und hat einen Wert von zB 1,234,567,890 (die Kommas sind nur fuer die bessere Lesbarkeit hier geschrieben worden). Wenn ich nun "a" "drucken" will, erhalte ich 1.2e10, also im "scientific" Format. Wie schaffe ich es, dass ich aber einen Ausgabe bekomme, die 1234567890 resp. 1234567890,00 bekomme. Wie muss also der Befehl lauten, um die Zahl als ganzes auszugeben?
Schau dir mal java.text.DecimalFormat an. Damit müsste es gehen. Gruß, Bernhard - -- "Regular ist rekursiv. Ein User ist ein Regular, wenn er von den Regulars als Regular angesehen wird." -- Sebastian Posner in de.alt.folklore.usenet -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (GNU/Linux) iD8DBQFDpTWRiGU2lt2vZFQRAkPEAJ9I1CnOe6MBub9x4I00Oaavsls/rgCeIvoB vod4FhS7qsQZy/XGR7O8dXg= =+TUA -----END PGP SIGNATURE-----
Am Sonntag 18 Dezember 2005 10:54 schrieb Christoph Merk:
Hi Liste,
hier wahrscheinlich eine ganz simple Frage fuer eingefleischte Java Programmierer: Ich will eine Variable ueber System.out.println(a) ausdrucken. a ist vom Type "long" und hat einen Wert von zB 1,234,567,890 (die Kommas sind nur fuer die bessere Lesbarkeit hier geschrieben worden). Wenn ich nun "a" "drucken" will, erhalte ich 1.2e10, also im "scientific" Format. Wie schaffe ich es, dass ich aber einen Ausgabe bekomme, die
Wie wäre es mit java.text.NumberFormat? sowas wie import java.text.NumberFormat; ....... NumFormat_Long = NumberFormat.getNumberInstance(); System.out.println(NumFormat_Long.format(a));
1234567890 resp. 1234567890,00 bekomme. Wie muss also der Befehl lauten, um die Zahl als ganzes auszugeben?
Für ne exakte Vorgabe der Nachkommastellen kannst Du natürlich auch mit z.B. NumFormat_Long.setMinimumFractionDigits(2); NumFormat_Long.setMaximumFractionDigits(2); auf exakt zwei festlegen (ob das bei ner long Variable sinnvoll ist, sei jetzt mal dahingestellt). PS: Mir fehlt jetzt irgendwie der Bezug zu den C++ Objekten ... -- Machs gut | http://www.iivs.de/schwinde/buerger/tremmel/ | http://packman.links2linux.de/ Manfred | http://www.knightsoft-net.de
participants (13)
-
adsci
-
Alexander Muthler
-
Andre Rudlaff
-
Bernhard Walle
-
Christoph Merk
-
Frank Lanitz
-
Johanns Schneider
-
Jörg Pauly
-
lothar.behrens@lollisoft.de
-
Manfred Tremmel
-
Markus Ruettimann
-
Michael Wenger
-
Oliver Baum