JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=2f9c903c88a5a5e0f01b89480bbeb2f4Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Smartpointer in C++

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Tutorials
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 13.01.2006, 08:51    Titel: Smartpointer in C++ Antworten mit Zitat

Smartpointer

In C++ wird, im Gegensatz zu anderen Sprachen, die Verwaltung des dynamischen Speichers dem Programmierer überlassen.
Dies ist einerseits gut, da man selbst die volle Kontrolle hat. Andererseits widerrum treten dadurch gerne (und leider nur zu oft) Speicherlecks auf. Selbst bei erfahrenen Programmierern die Ihren Code gut durchgeplant haben ist die Gefahr trotzdem gegeben.
Folgendes Beispiel verdeutlicht das Problem:

CPP:
#include <iostream>

typedef unsigned long dword;

class Foo
{
public:
        Foo()
        {
                std::cout << "Konstuktor von Foo\n";
        }

        ~Foo()
        {
                std::cout << "Destruktor von Foo\n";
        }

        dword Divide( dword a, dword b )
        {
                if ( b == 0 )
                        throw std::exception();

                std::cout << "Foo::Divide()\n";
                return a / b;
        }
};

int main(int argc, char *argv[])
{               
        try
        {
                Foo *bar = new Foo();
                std::cout << "Ergebniss ist: " << bar->Divide( 10, 0 ) << "\n";
                delete bar;
        }
        catch ( const std::exception &e )
        {
                std::cout << "Fehler aufgetreten\n";
        }

        return 0;
}


Dieses Programm wirft eine Exception wenn der Parameter b von Divide gleich 0 ist. In diesem Fall wird der Speicher, der für bar reserviert wurde aber niemals Freigegeben, was natürlich eine Speicherverschwendung ist.

Die Ausgabe des Programms sieht wie folgend aus:

Zitat:

Konstuktor von Foo
Fehler aufgetreten


Was ist also zu tuen? Es muss eine Möglichkeit gefunden werden um den Speicher trotzdem sicher freizugeben.
Und genau diese Möglichkeit bietet die Klasse auto_ptr der STL.
CPP:
int main(int argc, char *argv[])
{               
        try
        {
                std::auto_ptr< Foo > bar( new Foo() );
                std::cout << "Ergebniss ist: " << bar->Divide( 10, 0 ) << "\n";
        }
        catch ( const std::exception &e )
        {
                std::cout << "Fehler aufgetreten\n";
        }

        return 0;
}


Die Ausgabe des Programms sieht nun folgendermaßen aus:
Zitat:

Konstuktor von Foo
Destruktor von Foo
Fehler aufgetreten


Der Destruktor von Foo wird nun immer aufgerufen sobald das Programm den Gültigkeitsbereich von bar verlässt. Dies funktioniert da das auto_ptr Objekt auf dem Stack liegt und bei solchen Objekten der Destruktor immer aufgerufen wird wenn der dazugehörige Gültigkeitsbereich verlassen wird.

Zum Schluß noch eine kleine Anmerkung:
Auto Pointer dürfen nicht auf Speicherbereich verwendet werden die mehr als ein Element beinhalten (new[]). Dies würde ein undefiniertes Verhalten auslösen. Um trotzdem solche Speicherbereiche sicher freizugeben bietet die Boost Bibliothek ein Klassen an namens scopet_array.
Außerdem haben Auto Pointer ein merkwürdiges Kopierverhalten. Wird ein Objekt vom Typ auto_ptr kopiert so zeigt nur das Zielobjekt auf den reservierten Speicher, der Zeiger des Original wird auf NULL gesetzt. Dieses Verhalten kann durch Reverenzzähler verbessert werden. Die Boost Bibliothek bietet eine Klasse namens shared_ptr genau für diesen Fall an.

grüße

P.S.: Hier nochmals als PDF.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Patrick
Dark JLI Master



Anmeldedatum: 25.10.2004
Beiträge: 1895
Wohnort: Düren
Medaillen: Keine

BeitragVerfasst am: 13.01.2006, 09:21    Titel: Antworten mit Zitat

David
Schmuck Schmuck Smile Dickes Lob!

Anmerkung: Für Leute die Hardwareexceptions auffangen wollen (z.B. Division durch 0) können das mit der Win32API ganz easy machen!

http://www.germangamedev.de/index.php?site=faq&id=15

Dadurch muss nicht erst getestet werden ob etwas gültig ist Smile Knallt es, dann wird die exception geworfen und ruhe ist Smile Die fängt man auf und verarbeitet diese Wink
_________________
'Wer der Beste sein will muss nach Perfektion streben und jede Gelegenheit nutzen sich zu verbessern.' - KIA
[ German Game Dev | Boardsuche hilft sehr oft | Google rockt | Wie man Fragen richtig stellt | ICQ#: 143040199 ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Blubb-Tec
JLI'ler


Alter: 33
Anmeldedatum: 29.03.2005
Beiträge: 171
Wohnort: Düsseldorf
Medaillen: Keine

BeitragVerfasst am: 13.01.2006, 14:35    Titel: Antworten mit Zitat

das ist mal was wirklich nützliches Very Happy hat das auch nen haken?^^
_________________
www.planlos.de
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 13.01.2006, 14:42    Titel: Antworten mit Zitat

Hi!

Auf die kleinen Eigenheiten wurde ganz unten eingegangen. Ansonsten keine nennenswerten! Wink

grüße
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
3c0r1z
Mini JLI'ler



Anmeldedatum: 18.01.2006
Beiträge: 1

Medaillen: Keine

BeitragVerfasst am: 18.01.2006, 16:38    Titel: Antworten mit Zitat

Nur als Ergenzung: http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=auto_ptr#Answ
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Tutorials Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum