Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 13.01.2006, 07:51 Titel: Smartpointer in C++ |
|
|
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 |
|
|
Patrick Dark JLI Master
Anmeldedatum: 25.10.2004 Beiträge: 1895 Wohnort: Düren Medaillen: Keine
|
|
Nach oben |
|
|
Blubb-Tec JLI'ler
Alter: 33 Anmeldedatum: 29.03.2005 Beiträge: 171 Wohnort: Düsseldorf Medaillen: Keine
|
Verfasst am: 13.01.2006, 13:35 Titel: |
|
|
das ist mal was wirklich nützliches hat das auch nen haken?^^ _________________ www.planlos.de |
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 13.01.2006, 13:42 Titel: |
|
|
Hi!
Auf die kleinen Eigenheiten wurde ganz unten eingegangen. Ansonsten keine nennenswerten!
grüße |
|
Nach oben |
|
|
3c0r1z Mini JLI'ler
Anmeldedatum: 18.01.2006 Beiträge: 1
Medaillen: Keine
|
|
Nach oben |
|
|
|