Was passiert, wenn ich Speicher nicht freigebe?
-
Eine Frage allgemeiner Natur:
Was passiert, wenn ich dynamisch reservierten Speicher nicht freigebe?Immer höre ich davon, dass das furchtbar schlimm ist.
Was passiert da denn genau?Kann man dann NIE mehr auf den Speicher zurückgreifen?
Oder nur bis zum Ende des Programms?
Oder bis man neustartet?Ich bin im Moment mit Zeigern am experementieren und da will ich meine Risiken einschätzen können.
-
Bei Windows nur bis zum ende des Programms.
-
Kann man dann NIE mehr auf den Speicher zurückgreifen?

-
"Was passiert, wenn ich Speicher nicht freigebe?"
nichts. du ballerst nur dem ram voll und bekommst den nicht mehr leer, ohne dein programm zu beenden.
-
smart_ptr's lösen dein Problem auf einfache Weise

Anyway, solange die Speichermenge, welche nicht bis zum Programmende freigegeben werden soll, konstant ist und bleibt und kann man das Freigeben am Ende IMO ignorieren.
-
Darf ich dem ganzen eine kleine Zusatzfrage zum Thema hinzufügen?
Was passiert, wenn ich beispielsweise folgende Funktion habe:
char *return_a_cstring() { char *c = new char[20]; /* irgendwas in c schreiben ;D */ return c; }Und ich rufe die Funktion mehrmals im Programm auf. Wird der RAM
da auch verballert??
Theorethisch schätze ich schon.
Was habe ich dann für Alternativen, wenn zum Beispiel eine Funktion
einen Cstring zurückliefern soll mit der Binärdarstellung einer Zahl?
-
Ja, die Funktion füllt auf Dauer auch deinen Heap. Die "primitivste" Lösung dafür ist es, daß der Aufrufer den jeweils erhaltenen Pointer freigibt, wenn er ihn nicht mehr braucht:
char* data=return_a_string(); cout<<data<<endl;//oder was ähnliches - nutze den übergebenen String delete[] data;//Speicher wieder freigebenEleganter ist es, anstelle eines nackten Pointers einen Smart-Pointer zurückzugeben (z.B. boost::shared_array) oder STL-Container (vector<char>) oder -Strings zu verwenden, die sich selber um ihren Speicher kümmern.
-
ne0r! Die Frage ist eher, warum man einen nackten C-String zurück geben sollte? Wenn man was mit C-Strings machen will/muß, dann würde ich doch eher einen initialisierten char-Pointer als Parameter haben wollen:
void return_a_cstring(char *str, std::size_t length);Dein Beispiel würde ich eher unter "schlechtes Design" einordnen.
Und wenn ich C++ mache, würde ich dann sogar eher einen std::string oder std::wstring zurück geben. Dann muß sich niemand um die Freigabe kümmern. Oder einen Smartpoint std::auto_ptrstd::string.std::auto_ptr<std::string> return_a_string() { std::auto_ptr<std::string> str(new std::string()); /* irgendwas in str schreiben */ return str; }
-
Artchi schrieb:
Oder einen Smartpoint std::auto_ptrstd::string.
Meinst du nicht, daß DAS etwas übertrieben ist?
-
Ich muß zugeben, das ich das selten SO mache. Meistens gebe ich einfach std::wstring zurück und gut ist.
Aber, der auto_ptr kostet ja praktisch nichts. Würde allerdings das Copy-on-Write-Pattern (CoW) bei basic_string eine Implementierungspflicht sein, würde ich mir den Smartptr bei Strings IMMER sparen. Denn dann wäre basic_string ja praktisch selbst eine Art Smartptr. CoW soll ja so in etwas das Konzept sein...
std::auto_ptrstd::string habe ich aber tatsächlich schon an zwei drei Stellen in meinen realen Projekten. Da wo ich weiß, das die Strings seeeehr groß sein können, und CoW nicht garantiert ist. Aber mein Posting von ebend war auch eher provokativ gemeint.

-
@Artchi: wie stellst du dir vor dass eine Standardkonforme Implementierung von std::basic_string mit COW aussehen soll? Was machst du wenn sich jmd. ne non-const Reference auf einen char/wchar_t z.B. über den operator [] holt...?
Willst du den String dann gleich kopieren?Es gibt da zumindest einige Papers drüber warum std::basic_string mit COW nix bringt ODER eben nicht Standardkonform ist.
BTW: COW + Multithreading = Langsam
(interlocked instructions sind nicht gerade schnell)
-
Danke für die Aufklärung. Hab halt nur gedacht, das es CoW nur schwer zu implementieren ist. Und es deshalb nicht in jeder Implementierung drin ist. Wenn es auch andere Gründe gibt, dann ist das ja schon mal ein Hinweis.
Aber dann ist es doch erst Recht nicht falsch, wenn ich std::auto_ptrstd::string als Rückgabewert definiere?
-
hustbaer schrieb:
@Artchi: wie stellst du dir vor dass eine Standardkonforme Implementierung von std::basic_string mit COW aussehen soll? Was machst du wenn sich jmd. ne non-const Reference auf einen char/wchar_t z.B. über den operator [] holt...?
Willst du den String dann gleich kopieren?Genau. Die Formulierung im Standard kann da keine Zweifel lassen. Im Übrigen sind nur nicht-konstante Referenzen (Zeiger, Iteratoren) problematisch.
-
Artchi schrieb:
Aber dann ist es doch erst Recht nicht falsch, wenn ich std::auto_ptrstd::string als Rückgabewert definiere?
Natürlich nicht, hab ich nie behauptet

BTW: du kannst auch boost::shared_ptr<std::string const> verwenden, dann hast du fast sowas wie einen COW String. Bloss halt wieder das dumme "interlocked ist langsam" Problem -- unter dem leiden aber alle thread safe COW Implementierungen die ich so kenne.camper schrieb:
Im Übrigen sind nur nicht-konstante Referenzen (Zeiger, Iteratoren) problematisch.
Problematisch ist dass der operator [], und die Iteratoren (beim Dereferenzieren), eine Referenz zurückliefern müssen. Dürften sie einen Proxy zurückgeben wäre es nicht so ein Problem, der Proxy hätte dann einen operator = definiert welcher eben den String vor dem modifizieren kopiert.
-
hustbaer schrieb:
Artchi schrieb:
Aber dann ist es doch erst Recht nicht falsch, wenn ich std::auto_ptrstd::string als Rückgabewert definiere?
Natürlich nicht, hab ich nie behauptet

BTW: du kannst auch boost::shared_ptr<std::string const> verwenden, dann hast du fast sowas wie einen COW String. Bloss halt wieder das dumme "interlocked ist langsam" Problem -- unter dem leiden aber alle thread safe COW Implementierungen die ich so kenne.camper schrieb:
Im Übrigen sind nur nicht-konstante Referenzen (Zeiger, Iteratoren) problematisch.
Problematisch ist dass der operator [], und die Iteratoren (beim Dereferenzieren), eine Referenz zurückliefern müssen. Dürften sie einen Proxy zurückgeben wäre es nicht so ein Problem, der Proxy hätte dann einen operator = definiert welcher eben den String vor dem modifizieren kopiert.
Hätte... der Standard nicht extra COW-Implementationen ermöglicht, hätten wir auch kein Problem... und das erscheint mir die günstigere Lösung - das ist zudem etwas, was man noch ändern kann ohne damit existierenden Code (abgesehen von der Standardbibliothek selbst) kaputt zu machen. Es gibt gute Gründe dafür, dass der Standard fast nie mit Proxies arbeitet.
-
OK danke.
Ich werde dann wohl keine strings mehr von Funktionen zurückgeben lassem.
Ist mir zu kompliziert.
-
Also gut, da stimm ich obba zu. Sehr kompliziert...
Zumindest sagen mir die Begriffe da nix.Egal.
Jedenfalls war dies mein Anfangskonzept (Man bedenke, ich bin Anfänger):
template<class X> char* getbinary(const X &data) { X bit = 1; char *c = new char[8*sizeof(X)]+1; register char i; for(i = 8*sizeof(X) - 1; i >= 0; --i) { c[i] = (data & bit)? '1':'0'; bit = bit << 1; } c[8*sizeof(X)] = 0; return c; }Ich arbeite nämlich grad ein Buch durch, bei dem <string> erst jetzt, also fast am Schluss drankommt...
Ich werd das mit String lösen, denke ich.
Oder ich lern was das Zeug bedeutet, was ihr da labert.
Ach ja @Artchi:
Da hast du wohl Recht mit dem schlechten Design
-
P.S.:
Kritik stark erwünscht.
(Und sorry wegen dem Doublepost)
-
Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum Rund um die Programmierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
ne0r schrieb:
Kritik stark erwünscht.
Also für einen Anfänger sieht das doch gar nicht schlecht aus (abgesehen davon, daß das "+1" an der falschen Stelle steht - und ich die Array-Größe vermutlich als Konstante festgelegt hätte).
PS: Was hast du denn für ein Buch? In meinem stand "register" ziemlich weit hinten unter "was es noch gibt"
