C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Wird der irterator ungültig?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Markus Breuer
Guest





PostPosted: Wed Jun 09, 2004 7:56 am    Post subject: Wird der irterator ungültig? Reply with quote



Vor kurzem ging es um iteratoren/const_iteratoren und erase().
Hieraus ging hervor, dass der Iterator beim Aufruf von erase() nicht
verändert wird und lediglich als Selektionskriterium dient oder dienen
sollte.

Nun habe ich folgenden Code:

while ( it != container.end() )
{
container.erase( it );
delete *it; // ist das erlaubr?
it = container.begin();
}

Im Container befinden sich Zeiger auf andere Objekte, die Schleife
sollte alle Objekte zerstören und den Conatainer leeren. Ist obiger Code
zulässiges C++?

Markus

--
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
Hendrik Belitz
Guest





PostPosted: Wed Jun 09, 2004 8:38 am    Post subject: Re: Wird der irterator ungültig? Reply with quote



Markus Breuer wrote:

Quote:
Vor kurzem ging es um iteratoren/const_iteratoren und erase().
Hieraus ging hervor, dass der Iterator beim Aufruf von erase() nicht
verändert wird und lediglich als Selektionskriterium dient oder dienen
sollte.

Nun habe ich folgenden Code:

while ( it != container.end() )
{
container.erase( it );
delete *it; // ist das erlaubr?
it = container.begin();
}

Im Container befinden sich Zeiger auf andere Objekte, die Schleife
sollte alle Objekte zerstören und den Conatainer leeren. Ist obiger Code
zulässiges C++?

Markus


Ich hoffe schon, so mache ich das nämlich auch.

--
To get my real email adress, remove the two onkas
--
Hendrik Belitz
- Abort, Retry, Fthagn? -

--
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
Karl Heinz Buchegger
Guest





PostPosted: Wed Jun 09, 2004 8:42 am    Post subject: Re: Wird der irterator ungültig? Reply with quote



Markus Breuer wrote:
Quote:

Vor kurzem ging es um iteratoren/const_iteratoren und erase().
Hieraus ging hervor, dass der Iterator beim Aufruf von erase() nicht
verändert wird und lediglich als Selektionskriterium dient oder dienen
sollte.

Nun habe ich folgenden Code:

while ( it != container.end() )
{
container.erase( it );
delete *it; // ist das erlaubr?
it = container.begin();
}

Im Container befinden sich Zeiger auf andere Objekte, die Schleife
sollte alle Objekte zerstören und den Conatainer leeren. Ist obiger Code
zulässiges C++?

Nein. Nachdem Du erase losgelassen hast, ist der iterator ungueltig.

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

--
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
Falk Tannhäuser
Guest





PostPosted: Wed Jun 09, 2004 9:32 am    Post subject: Re: Wird der irterator ungültig? Reply with quote

Karl Heinz Buchegger wrote:
Quote:

Markus Breuer wrote:

Vor kurzem ging es um iteratoren/const_iteratoren und erase().
Hieraus ging hervor, dass der Iterator beim Aufruf von erase() nicht
verändert wird und lediglich als Selektionskriterium dient oder dienen
sollte.

???
Ein Iterator, der durch erase nicht ungültig wird? Wie'n dat?

Quote:

Nun habe ich folgenden Code:

while ( it != container.end() )
{
container.erase( it );
delete *it; // ist das erlaubr?
it = container.begin();
}

Im Container befinden sich Zeiger auf andere Objekte, die Schleife
sollte alle Objekte zerstören und den Conatainer leeren. Ist obiger Code
zulässiges C++?

Nein. Nachdem Du erase losgelassen hast, ist der iterator ungueltig.

Ack.
Was spricht eigentlich gegen

while ( it != container.end() )
{
delete *it;
*it = 0; // Wenn man gaaaaaaaaaaanz vorsichtig sein will...
container.erase( it );
it = container.begin();
}

oder gleich ganz klassisch

for(it = container.begin(); it != container.end(); ++it)
{
delete *it;
it = 0; // s.o.
}
container.clear();

Wenn man das oft genug braucht, lohnt es sich sicher, einen Funktor dafür
zu schreiben und for_each machen zu lassen.

MfG
Falk

--
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
Falk Tannhäuser
Guest





PostPosted: Wed Jun 09, 2004 9:38 am    Post subject: Re: Wird der irterator ungültig? Reply with quote

Was mir noch dazu einfällt: Es ist zu überlegen, ob
man wirklich nackichte Zeiger in einen Container
packen will und nicht lieber etwa boost::shared_ptr.
Da erase die Destruktoren aufruft, vereinfacht das
einiges, und man vermeidet Ärger, wenn man noch
Zeiger außerhalb des Containers auf die selben
Objekte hat.

Falk

--
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
Markus Breuer
Guest





PostPosted: Wed Jun 09, 2004 4:17 pm    Post subject: Re: Wird der irterator ungültig? Reply with quote

Falk Tannhäuser wrote:
Quote:
Was mir noch dazu einfällt: Es ist zu überlegen, ob
man wirklich nackichte Zeiger in einen Container
packen will und nicht lieber etwa boost::shared_ptr.
Da erase die Destruktoren aufruft, vereinfacht das
einiges, und man vermeidet Ärger, wenn man noch
Zeiger außerhalb des Containers auf die selben
Objekte hat.

Das ist reine Ansichtssache. Zum einen kann eine Container durchaus
auf Objekte verweisen, die mit dem entfernen des Containers erhalten
bleiben müssen. Beispielsweise hast du eine Liste, die Elemente
beinhaltet und einen sortierten vector, der mittels Pointer einen
schnellen Zugriff erlaubt.
Zum anderen ist auch der boost::shared_pointer nicht kostenlos, d.h. er
benötigt einen Teil der runtime. Ich habe die Erfahrung gemacht, dass
solche Gimmicks dazu verleiten, beim Design zu schlampen. Nein, ich
finde die boost-library sehr nützlich, nutze sie aber nur, wenn ich die
Funktionalität wirklich benötige.

Gruß Markus

--
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
Falk Tannhäuser
Guest





PostPosted: Wed Jun 09, 2004 5:04 pm    Post subject: Re: Wird der irterator ungültig? Reply with quote

Markus Breuer wrote:
Quote:

Falk Tannhäuser wrote:
Was mir noch dazu einfällt: Es ist zu überlegen, ob
man wirklich nackichte Zeiger in einen Container
packen will und nicht lieber etwa boost::shared_ptr.
Da erase die Destruktoren aufruft, vereinfacht das
einiges, und man vermeidet Ärger, wenn man noch
Zeiger außerhalb des Containers auf die selben
Objekte hat.

Das ist reine Ansichtssache. Zum einen kann eine Container durchaus
auf Objekte verweisen, die mit dem entfernen des Containers erhalten
bleiben müssen. Beispielsweise hast du eine Liste, die Elemente
beinhaltet und einen sortierten vector, der mittels Pointer einen
schnellen Zugriff erlaubt.

boost::shared_ptr ist genau dafür gedacht. Durch Referenzzählung wird
gesichert, dass das kontrollierte Objekt erst beim Verschwinden des
letzten Zeigers freigegeben wird.
Wenn man natürlich die Liste und den Vektor schön zusammenkapselt, so
dass Konsistenz und Abwesenheit von "dangling pointers" oder Lecks
durch das Design gesichert sind, mag man auch ohne auskommen.

Quote:
Zum anderen ist auch der boost::shared_pointer nicht kostenlos, d.h. er
benötigt einen Teil der runtime. Ich habe die Erfahrung gemacht, dass
solche Gimmicks dazu verleiten, beim Design zu schlampen. Nein, ich
finde die boost-library sehr nützlich, nutze sie aber nur, wenn ich die
Funktionalität wirklich benötige.

Klar kommt es immer darauf an, was gemacht wird. container<foo*> ist
z.B. dann OK, wenn dieser Container der "einzige Eigentümer" der gezeigten
Objekte ist; allgemeiner, wenn sichergestellt werden kann, dass nichts
zu früh freigegeben wird (d.h. verhindern, dass auf das freigegebene Objekt
noch über andere Zeiger zugegriffen wird) oder zu spät / gar nicht
(Ressourcenleck).
Natürlich sollte man sich nicht blindlings auf alle "Gimmicks" stürzen, ohne
sich über die Folgen bezüglich Ressourcenverbrauch / Laufzeit im klaren zu
sein. Die Entscheidung zwischen container<boost::shared_ptr,
container<foo*> o.a. sollte aber Ergebnis einer umfassenderen Analyse
der Vor- und Nachteile sein und man sollte zumindest die Möglichkeiten /
Grenzen dieser Lösungen kennen, um sie in Betracht ziehen zu können.
Ohne Kenntnis des Kontextes lässt sich keine allgemeine Aussage treffen.
Allerdings denke ich, dass man mit shared_ptr leichter zu einem korrekten
Programm kommt als mit simplen Zeigern, und ob der Laufzeit-Overhead
praktisch ins Gewicht fällt, lässt sich sicher oft nur mittels Profiling
feststellen.
C++ lässt einem ja hier (leider oder zum Glück) die Wahlfreiheit, im
Gegensatz z.B. zu Java, wo sowieso alles dem Garbage-Kollektor überlassen
wird.

MfG
Falk

--
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
Markus Breuer
Guest





PostPosted: Wed Jun 09, 2004 8:07 pm    Post subject: Re: Wird der irterator ungültig? Reply with quote

Quote:
Natürlich sollte man sich nicht blindlings auf alle "Gimmicks" stürzen, ohne
sich über die Folgen bezüglich Ressourcenverbrauch / Laufzeit im klaren zu
sein.

Das sehe ich auch so. Allerdings beobachte ich in dieser Newsgroup
regelmäßig, dass die erste pauschele Lösung in boost::shared_pointer
steckt. Dem Newcomer wird suggeriert hier ein Allheilmittel gefunden zu
haben.

Quote:
Die Entscheidung zwischen container<boost::shared_ptr,
container<foo*> o.a. sollte aber Ergebnis einer umfassenderen Analyse
der Vor- und Nachteile sein und man sollte zumindest die Möglichkeiten /
Grenzen dieser Lösungen kennen, um sie in Betracht ziehen zu können.
Ohne Kenntnis des Kontextes lässt sich keine allgemeine Aussage treffen.
Allerdings denke ich, dass man mit shared_ptr leichter zu einem korrekten
Programm kommt als mit simplen Zeigern, und ob der Laufzeit-Overhead
praktisch ins Gewicht fällt, lässt sich sicher oft nur mittels Profiling
feststellen.

Die Gefahr steckt weniger in der grundsätzlichen Verwendung dieses
Pointers, als vielmehr in der leichtsinnigen Anwendung. Im ersten
Schritt nimmt mir der SmartPointer etwas Arbeit ab. Weil's so schön ist,
geize ich nicht mit dem Einsatz, dann kommt multi-Threading ins Spiel -
und weil's wieder so einfach ist - und die SmartPointer werden durch
Mutexe geschützt. Und weil's wieder so einfach ist, per default für die
gesamte Applikation. Unter dem Strich mache ich mir keine Gedanken mehr
über die Datenströme in meiner Applikation, kommt Profiling in das
Spiel, so hätten "normale" Pointer hier auch keine Vorteile gebracht.
Dabei hätte man sich mit normalen Pointern meiner Meinung nach viel
früher Gedanken gemacht ...

Quote:
C++ lässt einem ja hier (leider oder zum Glück) die Wahlfreiheit, im
Gegensatz z.B. zu Java, wo sowieso alles dem Garbage-Kollektor überlassen
wird.

Mit dem SmartPtr schafft man ja so etwas wie einen Garbage-Kollektor.

Gruß Markus

--
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
Rene Moehring
Guest





PostPosted: Thu Jun 10, 2004 6:43 am    Post subject: Re: Wird der irterator ungültig? Reply with quote

On Wed, 09 Jun 2004 22:07:18 +0200, Markus Breuer wrote:
Quote:

Mit dem SmartPtr schafft man ja so etwas wie einen Garbage-Kollektor.

Aber im Gegensatz zum Java-GC weiß man wann der SmartPtr zuschlägt,
nämlich wenn die letzte Referenz verschwindet. Sehe ich persönlich als
Vorteil an.
--
I'm not a racist. I hate everyone equally!

--
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
kanze@gabi-soft.fr
Guest





PostPosted: Thu Jun 10, 2004 8:02 am    Post subject: Re: Wird der irterator ungültig? Reply with quote

Falk Tannhäuser <falk.tannhauser (AT) crf (DOT) canon.fr> wrote

Quote:
Karl Heinz Buchegger wrote:

Markus Breuer wrote:

Vor kurzem ging es um iteratoren/const_iteratoren und erase().
Hieraus ging hervor, dass der Iterator beim Aufruf von erase()
nicht verändert wird und lediglich als Selektionskriterium dient
oder dienen sollte.

???
Ein Iterator, der durch erase nicht ungültig wird? Wie'n dat?

Wenn man den gezeigten Element löscht, kenne ich keine (in der STL -- in
meiner vor-Standards Bibliothek klappt es). Wenn man einen anderen
Element löscht, kommt auf dem Container.

Quote:
Nun habe ich folgenden Code:

while ( it != container.end() )
{
container.erase( it );
delete *it; // ist das erlaubr?

Ganz und gar nicht. Auch in meine vor-Standards Implementierung konnte
man nicht auf einen nicht mehr existierenden Element zugreifen.

Quote:
it = container.begin();
}

Im Container befinden sich Zeiger auf andere Objekte, die Schleife
sollte alle Objekte zerstören und den Conatainer leeren. Ist
obiger Code zulässiges C++?

Nein. Nachdem Du erase losgelassen hast, ist der iterator ungueltig.

Ack.
Was spricht eigentlich gegen

while ( it != container.end() )
{
delete *it;
*it = 0; // Wenn man gaaaaaaaaaaanz vorsichtig sein will...

Streng genommen hast du hier auch undefiniertes Verhalten. Laut der
Norm. Laut der Norm muss man schreiben:

T* tmp = *it ;
container.erase( it ) ;
delete tmp ;

In der Praxis wird's immer funktionnieren.

Quote:
container.erase( it );
it = container.begin();
}

oder gleich ganz klassisch

for(it = container.begin(); it != container.end(); ++it)
{
delete *it;
it = 0; // s.o.
}
container.clear();

Eigentlich ist das auch wahrscheinlich am schnellsten. Für mich aber ist
"klassisch":

while ( ! container.empty() ) {
delete container.back() ;
container.pop_back() ;
}

Oder, wenn ich auf der undefinierten Verhältnis verzichten will:

while ( ! container.empty() ) {
T* tmp = container.back() ;
container.pop_back() ;
delete tmp ;
}

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

--
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
Markus Breuer
Guest





PostPosted: Thu Jun 10, 2004 7:09 pm    Post subject: Re: Wird der irterator ungültig? Reply with quote

Rene Moehring wrote:
Quote:
On Wed, 09 Jun 2004 22:07:18 +0200, Markus Breuer wrote:

Mit dem SmartPtr schafft man ja so etwas wie einen Garbage-Kollektor.


Aber im Gegensatz zum Java-GC weiß man wann der SmartPtr zuschlägt,
nämlich wenn die letzte Referenz verschwindet. Sehe ich persönlich als
Vorteil an.

Wenn du genau im Auge hast, welches derletzte Pointer ist, dann ja. Wenn
der letzte Pointer irgendwo steht, wo du ihn nicht mehr im Blickfeld
hast, wird es schon komplizierter. Und wenn du komplizierte
Datenstrukturen miteinander verwurschtelst und Objekte einander
Referenzieren, genügt es den letzten SmartPointer im Hauptprogramm zu
löschen um ein Memory-Leak zu erzeugen. Die Objekte referenzieren
einanderer, nur kommst du nicht mehr an die Objekte heran. Solche Fehler
diagnostiziert man nur schwer ...

Ich bleibe bei meiner Meinung: die sparsame Anwendung am richtigen Ort
ist okay, aber zuviel des "Guten" kann sich schnell rächen.

Gruß Markus

--
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
C. Gerald Knizia
Guest





PostPosted: Fri Jun 11, 2004 6:52 am    Post subject: Re: Wird der irterator ungültig? Reply with quote

Rene Moehring schrieb:
Quote:
On Wed, 09 Jun 2004 22:07:18 +0200, Markus Breuer wrote:
Mit dem SmartPtr schafft man ja so etwas wie einen Garbage-Kollektor.

Aber im Gegensatz zum Java-GC weiß man wann der SmartPtr zuschlägt,
nämlich wenn die letzte Referenz verschwindet. Sehe ich persönlich als
Vorteil an.

Wenn man genau weiß, wo der letzte Pointer auf ein Objekt steht (was
praktisch immer der Fall ist, wenn man konkrete Ownershiphirarchien hat, was
ebenfalls sehr wünschenswert ist), dann braucht man auch keine shared_ptr -
etwas im Sinne eines Scope- oder Auto Ptrs reicht dann völlig.
--
- C. Gerald Knizia/cgk | #28673212 | this post was made with intention

--
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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.