 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Torsten Mohr Guest
|
Posted: Sat Nov 08, 2003 6:26 pm Post subject: Klasse erzeugt Klasse: Speicherleck vermeiden |
|
|
Hallo,
ich habe eine Klasse, die Objekte einer anderen Klasse erzeugt
und zurückliefert. Diese Objekte, die ich per "new" erzeugen
möchte, sollten ja auch irgendwann wieder zerstört werden,
was ja nicht mehr direkt im Bereich der Klasse liegt.
Kann die Klasse das denn irgendwie unterstützen?
Für das Erzeugen der Objekte gäbe es ja mehrere Möglichkeiten:
1:
Object* getNewObjekt();
Hier könnte der Benutzer der Objekte irgendwann durcheinander
kommen und die Objekte nicht mehr zerstören.
2:
Object anObj;
getNewObjekt(Object& obj);
Hier könnte die Methode testen, ob schon ein Objekt angelegt
wurde und dieses dann vor Anlegen eines neuen zerstören.
Welche weiteren Möglichkeiten gäbe es da noch um in diese
Angelegenheit mehr Sicherheit reinzubringen?
Danke für Tipps,
Torsten.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Sun Nov 09, 2003 9:08 am Post subject: Re: Klasse erzeugt Klasse: Speicherleck vermeiden |
|
|
Torsten Mohr <tmohr@s.netic.de> writes:
| Quote: | ich habe eine Klasse, die Objekte einer anderen Klasse erzeugt
und zurückliefert. Diese Objekte, die ich per "new" erzeugen
möchte, sollten ja auch irgendwann wieder zerstört werden,
was ja nicht mehr direkt im Bereich der Klasse liegt.
Kann die Klasse das denn irgendwie unterstützen?
|
Ja.
| Quote: | Welche weiteren Möglichkeiten gäbe es da noch um in diese
Angelegenheit mehr Sicherheit reinzubringen?
|
std::auto_ptr<Object> getNewObject();
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Marco Budde Guest
|
Posted: Sun Nov 09, 2003 9:59 am Post subject: Re: Klasse erzeugt Klasse: Speicherleck vermeiden |
|
|
Torsten Mohr wrote:
| Quote: | 1:
Object* getNewObjekt();
Hier könnte der Benutzer der Objekte irgendwann durcheinander
kommen und die Objekte nicht mehr zerstören.
|
Das ist genau die Art von Code die bei Sprachen ohne GC nicht
wirklich toll ist. Sowas sollte man, wenn es möglich ist, vermeiden.
| Quote: | getNewObjekt(Object& obj);
Hier könnte die Methode testen, ob schon ein Objekt angelegt
wurde
|
Wieso soll sie das testen? Das ist bei einer Referenz immer der
Fall.
| Quote: | und dieses dann vor Anlegen eines neuen zerstören.
|
Nein, das kann sie nicht.
| Quote: | Welche weiteren Möglichkeiten gäbe es da noch um in diese
Angelegenheit mehr Sicherheit reinzubringen?
|
Smart Pointer?
cu, Marco
--
S: Minolta: Winkelsucher (VN), VC-9
E-Mail: mb-news-b<ät>linuxhaven.de
Deutsches Linux HOWTO Projekt: http://www.linuxhaven.de
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Mon Nov 10, 2003 10:43 am Post subject: Re: Klasse erzeugt Klasse: Speicherleck vermeiden |
|
|
Hallo,
Torsten Mohr <tmohr@s.netic.de> wrote:
| Quote: | ich habe eine Klasse, die Objekte einer anderen Klasse erzeugt
und zurückliefert. Diese Objekte, die ich per "new" erzeugen
möchte, sollten ja auch irgendwann wieder zerstört werden,
was ja nicht mehr direkt im Bereich der Klasse liegt.
Kann die Klasse das denn irgendwie unterstützen?
Für das Erzeugen der Objekte gäbe es ja mehrere Möglichkeiten:
1:
Object* getNewObjekt();
Hier könnte der Benutzer der Objekte irgendwann durcheinander
kommen und die Objekte nicht mehr zerstören.
|
Dagegen helfen Smart Pointer in einer Geschmacksrichtung deiner
Wahl. Das fängt bei std::auto_ptr an und hört bei
boost::shared_ptr noch lange nicht auf.
| Quote: | 2:
Object anObj;
getNewObjekt(Object& obj);
Hier könnte die Methode testen, ob schon ein Objekt angelegt
wurde und dieses dann vor Anlegen eines neuen zerstören.
|
Das habsch jetzt ni kapiert.
Egal, ich verwende in letzter Zeit etwas unkonventionelleres.
class Object {
public:
virtual ~Object() { }
};
class ObjectHolder {
std::vector<Object*> v;
public:
template<class T> T& add(T* p) { v.push_back(p); return *p; }
~ObjectHolder() {
while(v.size()) {
Object* p = 0; swap(v.back(), p); delete p; v.pop_back();
}
}
};
Eine Factory-Funktion hat dann die Signatur
Klasse& createObject(ObjectHolder& h);
und macht z.B.
return h.add(new MeineSuperKlasse());
Wenn ich eine Factory-Funktion aufrufen will, muß ich mir also
Gedanken machen, wie ich das Objekt wieder loswerde. Im
Gegensatz zur Verwendung von Smart Pointern ist das sogar recht
speicherplatz-effizient.
Ein paar mehr Gedanken von mir zu dem Thema hatte ich in
Message-Id: <1058799995.irz782%sr21 (AT) inf (DOT) tu-dresden.de> ff
im Juli aufgeschrieben.
Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Mon Nov 10, 2003 5:20 pm Post subject: Re: Klasse erzeugt Klasse: Speicherleck vermeiden |
|
|
Stefan Reuther wrote:
| Quote: | Hallo,
snip
Egal, ich verwende in letzter Zeit etwas unkonventionelleres.
class Object {
public:
virtual ~Object() { }
};
class ObjectHolder {
std::vector<Object*> v;
public:
template<class T> T& add(T* p) { v.push_back(p); return *p; }
~ObjectHolder() {
while(v.size()) {
Object* p = 0; swap(v.back(), p); delete p; v.pop_back();
}
}
};
Eine Factory-Funktion hat dann die Signatur
Klasse& createObject(ObjectHolder& h);
und macht z.B.
return h.add(new MeineSuperKlasse());
|
Und hier haben wir jetzt ein Speicherleck, wenn der vector in
ObjectHolder nicht mehr genügend Speicher bekommt, um den Zeiger zu
speichern. Ein auto_ptr in ObjectHolder::add, kann das (zugegeben,
ansatzweise akademische Problem lösen.
mfg Torsten
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Tue Nov 11, 2003 11:41 am Post subject: Re: Klasse erzeugt Klasse: Speicherleck vermeiden |
|
|
Hallo,
Torsten Robitzki <firstname (AT) lastname (DOT) de> wrote:
| Quote: | Stefan Reuther wrote:
template<class T> T& add(T* p) { v.push_back(p); return *p; }
Und hier haben wir jetzt ein Speicherleck, wenn der vector in
ObjectHolder nicht mehr genügend Speicher bekommt, um den Zeiger zu
speichern. Ein auto_ptr in ObjectHolder::add, kann das (zugegeben,
ansatzweise akademische Problem lösen.
|
Das war auch nur die Light-Version für das Posting.
In der Vollversion steht:
private:
void addObject(Object* p) {
try { v.push_back(p); }
catch (...) { delete p; throw; }
}
public:
template<class T> T& add(T* p) { addObject(p); return *p; }
Genauer gesagt, steht das auch nicht *so* da, sondern 'addObject'
ist eine non-inline Funktion, damit ich das ganze Exception-
Geraffel nur einmal in der .exe stehen habe.
Zufrieden? :-)
Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Tue Nov 11, 2003 4:38 pm Post subject: Re: Klasse erzeugt Klasse: Speicherleck vermeiden |
|
|
Stefan Reuther wrote:
| Quote: | Hallo,
Torsten Robitzki <firstname (AT) lastname (DOT) de> meckerte:
Stefan Reuther wrote:
template<class T> T& add(T* p) { v.push_back(p); return *p; }
Und hier haben wir jetzt ein Speicherleck, wenn der vector in
ObjectHolder nicht mehr genügend Speicher bekommt, um den Zeiger zu
speichern. Ein auto_ptr in ObjectHolder::add, kann das (zugegeben,
ansatzweise akademische Problem lösen.
Das war auch nur die Light-Version für das Posting.
In der Vollversion steht:
private:
void addObject(Object* p) {
try { v.push_back(p); }
catch (...) { delete p; throw; }
}
public:
template<class T> T& add(T* p) { addObject(p); return *p; }
Genauer gesagt, steht das auch nicht *so* da, sondern 'addObject'
ist eine non-inline Funktion, damit ich das ganze Exception-
Geraffel nur einmal in der .exe stehen habe.
Zufrieden?
|
Ja, so ist es viel schöner ;-)
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|