Char array übergabe
-
sluz schrieb:
Kommt jemals delete this; vor, dann machst du fast sicher etwas falsch, weil du dir dadurch selber das Bein abschießt
Wieso sollte man damit etwas falsch machen? Wenn in dem Fall ein Socket kaputt ist, wieso auch immer, dann zerstöre ich das Object. Für jede Verbindung wird bei mir ein Object erstellt. Und damit die sich nicht ansammeln müssen ja die defekten mal raus.
delete thisist *sehr* unschoenes Design. Wenn du dann noch ein Stackobjekt erstellst, wirds harig - und das kannst du nicht NICHT garantieren, ausser du bastelst dir eine factory mit ueberladenemoperator newusw. BUARKS
-
Schon klar was die Stacks anbelangt und so, aber in MEINEM speziellen Fall ist es einfacher die Objekte sich selber killen zu lassen und über den Destructor sich aus dem global erreichbaren Stack zu löschen.
-
sluz schrieb:
global erreichbaren Stack
Das ist es gerade. Du darfst nur Speicher freigeben, der im Heap allokiert wurde. Das der von deiner Instanz (
*this) aber auch mit bspw.newallokiert wurde, garantiert keiner.
-
Ach ****, habe an das richtige gedacht und das falsche geschrieben - ist natürlich alles im Heap - und darauf wurde explizit beim coden geachtet das halt kein Problem damit ensteht.
Weiß jetzt aber auch was ihr meint und worauf ihr hinaus wolltet, danke euch

-
sluz schrieb:
Weiß jetzt aber auch was ihr meint und worauf ihr hinaus wolltet, danke euch

Nein, du weißt, worauf Sone hinaus will, aber nicht worauf ein vernünftiger Mensch hinaus möchte
: Was passiert, wenn du später auf Member zugreifst? Bämm! Außerdem: Wie erfährt der Rest des Programms, dass das Objekt sich soeben selber zerstört hat? Der Aufrufer der Funktion hat immer noch seinen Pointer auf das Objekt und wird ihn wieder benutzen. Bämm!Von dem was du anscheinend erreichen möchtest, suchst du eine Exception, keinen Selbstmord.
-
MAN! SeppJ!
Du weißt doch nicht mal wie mein Globaler Speicher aussieht, in dem meine Objekte liegen und schon urteilst du darüber, dass er hier und da Fehler verursacht. Aber hier einmal zur Info : auf die Objekte wir über eine statische Klasse zugegriffen in der überprüft wird ob das Objekt valide ist oder nicht.
Wenn du dennoch der Meinung bist, du könntest mich eines besseren belehren, dann lass uns wo anders unterhalten und hier nicht spammen
-
SeppJ schrieb:
sluz schrieb:
Weiß jetzt aber auch was ihr meint und worauf ihr hinaus wolltet, danke euch

Nein, du weißt, worauf Sone hinaus will, aber nicht worauf ein vernünftiger Mensch hinaus möchte

Das war einer der Gruende, wieso
delete thisbeschissen ist.DAS ist auch einer der Gruende wieso ich mich von der Irrlicht Engine distanziert habe.
http://irrlicht.sourceforge.net/docu/_i_reference_counted_8h_source.html#l00116
-
sluz schrieb:
MAN! SeppJ!
[...]
Wenn du dennoch der Meinung bist, du könntest mich eines besseren belehren, dann lass uns wo anders unterhalten und hier nicht spammen
Wenn du meinst, dass du mit
auf die Objekte wir über eine statische Klasse zugegriffen in der überprüft wird ob das Objekt valide ist oder nicht.
mich auch nur irgendwie überzeugen könntest, dass hier irgendetwas sinnvolles vorgeht, dann hast du gerade das Gegenteil erreicht. Hör auf mit dem C/Java-Denk (ich bin mir nicht mir sicher, welche Programmiersprache du gerade nachzumachen versuchst): C++ ist anders!
Einen brauchbarem Lösungsvorschlag erhältst du, wenn du verrätst, was du genau erreichen möchtest.
-
Eine Lösung habe ich schon lange, willst du wirklich sehen, was ich versuche aufzubauen? Aber na gut - Ich baue einen kleinen Instant-Messenger auf Basis von libev/GTK/polarssl.
Der delete this Teil ist ein Part vom libev loop indem die SSL Sockets angenommen werden und neue Objekte ( Clients ) mit allen Socket relevanten Informationen erstellt werden.
Es werden dann aber auch wirklich alle im Heap erstellt ( weswegen ich auch delete this bedenkenlos anwenden kann ), diese Pointer lagere ich in einer Static Klasse aus, damit ich vom Frontend auf die einzelnen Clients zugreifen kann.
-
sluz schrieb:
Es werden dann aber auch wirklich alle im Heap erstellt ( weswegen ich auch delete this bedenkenlos anwenden kann ),
Das ist ein sauhaessliches Design.
-
//Nachtrag
Achso und delete this wird ja nur aufgerufen wenn der Socket hinne ist - und wenn der Socket defekt ist, hat das ganze Objekt keinen Sinn mehr.Diese Objekte arbeiten alle selbstständig in dem ev-Loop und werden sonst nicht von irgend einer anderen Klasse oder so überwacht - daher müssen die sich selber bereinigen wenn was nicht stimmt.
UND
Ich dachte, ein halbwegs geistlich labiler Programmierer wuerde ALLERHOECHSTENS im Destruktor delete this; schreiben. Alles andere ist Wahnsinn.
Welchen Sinn macht es im destructor delete this aufzurufen wenn das Objekt in dem Moment schon zerstört wird? Gerade das erscheint mir unlogisch zu sein.
-
sluz schrieb:
Gerade das erscheint mir unlogisch zu sein.
Ja, da hab ich dank einem Denkfehler Meilenweit verfehlt. Entschuldige.
Trotzdem ist es haesslich.
-
Sone,
schau dir mal bitte den Code hier an - http://www.skitoy.com/p/writing-an-echo-server-in-libev-and-c/375Zeile 107 & 159 wären da relevant - kannst mir dann auch gerne sagen, dass das auch hässlicher Code ist, aber dann würde ich sehr gerne mal sehen wie "schöner" Code aussieht und wie man es lösen könnte.
-
sluz schrieb:
Zeile 107 & 159 wären da relevant - kannst mir dann auch gerne sagen, dass das auch hässlicher Code ist, aber dann würde ich sehr gerne mal sehen wie "schöner" Code aussieht und wie man es lösen könnte.
Ohne das jetzt so anzusehen, wuerde ich falls eine Heap-Allokation wirklich noetig ist einfach Smart-Pointer statt rohe Pointer bei der Instanziierung nehmen.
Also statt
EchoInstance* ptr = new EchoInstance(...); //das std::unique_ptr<EchoInstance> ptr( new EchoInstance(...) );Nennt sich RAII

-
Smartpointer schön und gut - aber das ändert leider nichts daran, dass sich die Objekte selber bereinigen müssen wenn der Socket im Objekt hinne ist.
Und gerade an dem Punkt sehe ich keine andere Lösung als sich selber zu Töten - sonst hat ja keiner drauf Zugriff um zu testen ob das Objekt noch in Takt ist oder nicht. Muss halt von innen passieren.
-
sluz schrieb:
Smartpointer schön und gut - aber das ändert leider nichts daran, dass sich die Objekte selber bereinigen müssen wenn der Socket im Objekt hinne ist.
.....

Schau mal, was Smartpointer sind.
-
std::unique_ptr<EchoInstance> ptr( new EchoInstance(...) );Und danach? Lässt du den Client in der nächsten Zeile sterben, wenn die Funktion zurückkehrt?
Prinzipiell kann man
delete this;zwar machen, aber dann sollte der Konstruktor nicht öffentlich sein. Stattdessen bietest du eine statische create()-Methode an, die eine Instanz korrekt erzeugt.
-
Athar schrieb:
Und danach? Lässt du den Client in der nächsten Zeile sterben, wenn die Funktion zurückkehrt?
Ich deklariere ihn da, wo ich ihn brauche... wenn er weiterleben soll, wird das ueber Move-Semantik geklaert (
return unique_ptr<..>(..);) oder ueber einenshared_ptr.Auf jeden fall so, dass
- semantisch garantiert wird dass der Speicher freigegeben wird
- Kein
delete thisim Code steht.
-
Da Sone hier ja den Fundamentalisten spielt, will ich im Gegensatz zu ihm mit mehr Argumenten antworten.
In der C++ FAQ sind die Bedingungen aufgeführt, die erfüllt sein müssen, um
delete this;einzusetzen. Hinweisen möchte ich insbesondere auf Regel 3:3.) You must be absolutely 100% positively sure that the rest of your member function (after the delete this line) doesn't touch any piece of this object (including calling any other member functions or touching any data members).
Jetzt dein Code:
void sslSocketS::recvSocket ( char *data ) { if ( !validSocket() ) { info ( "Socket ist broken!" ); delete this; }; ... ssize_t size = ssl_read ( m_ssl, (unsigned char*) data, MAXRECV + 1 ); ... }Auch wenn man nur vermuten kann, da du deine Klassendeklaration nicht angegeben hast, würde ich behaupten, dass
ssl_read()undm_sslMember deinersslSocketS-Klasse sind.
Damit hat dein Code, für den Fall, dassdelete this;ausgeführt wird, undefiniertes Verhalten.
Ich glaube auch, dass dein gepostetes Beispielprogramm nicht korrekt ist. Dort wird in der Funktionread_cb()delete this;aufgerufen. Dem Aufruf vonread_cb()in Zeile 60 folgt in Zeile 65 der Zugriff auf die Membervariablewrite_queue. Also auch hier potentiell undefiniertes Verhalten.Ich hoffe, du siehst ein, wie gefährlich der Gebrauch von
delete this;ist und solltest es deshalb komplett vermeiden. Wie schon angesprochen lassen sich selbst die meisten Vorkommen vondeletevermeiden, in dem man RAII zur Resourcenvewaltung einsetzt.
-
sluz schrieb:
Eine Lösung habe ich schon lange, willst du wirklich sehen, was ich versuche aufzubauen? Aber na gut - Ich baue einen kleinen Instant-Messenger auf Basis von libev/GTK/polarssl.
Der delete this Teil ist ein Part vom libev loop indem die SSL Sockets angenommen werden und neue Objekte ( Clients ) mit allen Socket relevanten Informationen erstellt werden.
Es werden dann aber auch wirklich alle im Heap erstellt ( weswegen ich auch delete this bedenkenlos anwenden kann ), diese Pointer lagere ich in einer Static Klasse aus, damit ich vom Frontend auf die einzelnen Clients zugreifen kann.
Also hat die statische Klasse (ich nenn diese einfach die Verwalterklasse) ein Pointer-Array, in dem die Sockets sind, und wenn die Sockets nicht funktionieren, lässt du sie mit delete this zerstören? Stell mich richtig, wenn ich dein Design nicht ganz durchschaue.