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 

selbst geschriebene Iteratoren

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





PostPosted: Sat Nov 04, 2006 5:39 am    Post subject: selbst geschriebene Iteratoren Reply with quote



Hallo,

ich schreibe gerade einen eigenen Iterator, der für eine eigene
Datenstruktur definiert ist. Diese Datenstruktur liefert - genaus wie
bei der STL - mit start() einen Iterator auf das erste Element in meiner
Datenstruktur. Entsprechend liefert end() das letzte Element.

Was aber passiert, wenn meine Datenstruktur noch überhaupt keine
Elemente speichert?

Wenn ich z.B. einen std::vector::iterator aus einem leeren std::vector
dereferenziere, dann bekomme ich eine Instanz, deren Adresse 0 ist.

vector<Myclass> v;
vector<Myclass>::iterator iter = v.begin();
Myclass & mc = *iter
cout << &mc << endl;

Benutze ich diese Instanz, dann liefert das natürlich eine
Speicherschutzverletzung.

Wie implementiert man so etwas?

Steht in dem Code der STL tatsächlich so etwas wie

[...]
if(vector.size == 0){
return *NULL;
}
[...]

bei der Implementierung des Iterators?

Würde bei so etwas der Compiler nicht vollkommen durchdrehen?

Was habt ihr für Vorschläge, wie man am geschicktesten ausdrückt, dass
gerade ein Iterator eines leeren Containers dereferenziert wird. Ich
habe schon an Exceptions gedacht, aber es macht nicht unbedingt sehr
viel Spaß, jedes mal Exceptions abzufangen, wenn man über einen
Container iteriert.

Danke und Grüße

Boris
Back to top
Guest






PostPosted: Sat Nov 04, 2006 9:06 am    Post subject: Re: selbst geschriebene Iteratoren Reply with quote



Boris Glawe schrieb:

Quote:
Hallo,

ich schreibe gerade einen eigenen Iterator, der für eine eigene
Datenstruktur definiert ist. Diese Datenstruktur liefert - genaus wie
bei der STL - mit start() einen Iterator auf das erste Element in meiner
Datenstruktur. Entsprechend liefert end() das letzte Element.

end() liefert eins nach dem letzen Element.
der iterator, der von end() zurueckgegeben wird, zeigt also nicht auf
ein element
und es ist nicht erlaubt, den zu dereferenzieren.

Quote:

Was aber passiert, wenn meine Datenstruktur noch überhaupt keine
Elemente speichert?

dann ist begin() == end()

Quote:

Wenn ich z.B. einen std::vector::iterator aus einem leeren std::vector
dereferenziere, dann bekomme ich eine Instanz, deren Adresse 0 ist.

das ist undefiniert, weil der speicher eines leeren vectors undefiniert
ist,
so wie der speicher, der zwar schon alloziert ist, aber noch nicht fuer
Elemente
gebraucht wird.
Wahrscheinlich ist der gerade null, weil er frisch alloziert wurde.

Quote:

vector<Myclass> v;
vector<Myclass>::iterator iter = v.begin();
Myclass & mc = *iter
cout << &mc << endl;

Benutze ich diese Instanz, dann liefert das natürlich eine
Speicherschutzverletzung.

Wie implementiert man so etwas?

Steht in dem Code der STL tatsächlich so etwas wie

[...]
if(vector.size == 0){
return *NULL;
}
[...]

das steht da nicht

Quote:

bei der Implementierung des Iterators?

Würde bei so etwas der Compiler nicht vollkommen durchdrehen?

nur wenn er betrunken ist

Quote:

Was habt ihr für Vorschläge, wie man am geschicktesten ausdrückt, dass
gerade ein Iterator eines leeren Containers dereferenziert wird. Ich
habe schon an Exceptions gedacht, aber es macht nicht unbedingt sehr
viel Spaß, jedes mal Exceptions abzufangen, wenn man über einen
Container iteriert.

ich schlag vor, noch mal die doku auf sgi.com/tech/stl zu lesen Wink
ansonsten gibt es da die iterator adaptor bibliothek von boost, die
das bauen von iteratoren sehr vereinfacht.

Quote:

Danke und Grüße

Boris
Back to top
Marc Wieden
Guest





PostPosted: Sat Nov 04, 2006 2:49 pm    Post subject: Re: selbst geschriebene Iteratoren Reply with quote



Hallo erstmal!

On Sat, 04 Nov 2006 00:39:34 +0100, Boris Glawe <boris@boris-glawe.de> wrote:
Quote:

Wenn ich z.B. einen std::vector::iterator aus einem leeren std::vector
dereferenziere, dann bekomme ich eine Instanz, deren Adresse 0 ist.

vector<Myclass> v;
vector<Myclass>::iterator iter = v.begin();
Myclass & mc = *iter
cout << &mc << endl;

Benutze ich diese Instanz, dann liefert das natürlich eine
Speicherschutzverletzung.

Wie implementiert man so etwas?

Man hat üblicherweise innerhalb der Containerklasse einen Zeiger auf
das erste Element. Der ist 0 wenn der Container keine Elemente enthält.

Quote:
Steht in dem Code der STL tatsächlich so etwas wie

[...]
if(vector.size == 0){
return *NULL;
}
[...]

bei der Implementierung des Iterators?

S.o., es wird der Start-Zeiger in einen entsprechenden iterator
umgewandelt.

Quote:
Würde bei so etwas der Compiler nicht vollkommen durchdrehen?

Was habt ihr für Vorschläge, wie man am geschicktesten ausdrückt, dass
gerade ein Iterator eines leeren Containers dereferenziert wird.

Wie drückst du aus, das der Iterator am Ende angelangt ist? Wie ist also
der Wert den end() zurückliefert? Ist der Container leer, ist
start()==end().

Quote:
Ich habe schon an Exceptions gedacht, aber es macht nicht unbedingt sehr
viel Spaß, jedes mal Exceptions abzufangen, wenn man über einen
Container iteriert.

Will man wirklich nur iterieren schreib man ja üblicherweise:
for (vector<Myclass>::iterator it=v.begin()
;it!=v.end()
;++it){...

ist nun v.begin()==v.end() bricht die Schleife sofort ab.
Will man nur den Startwert benutzen, wie in deinem Beispiel oben, muß
man vor dem Dereferenzieren explizit auf !=end() testen.

Marc
--
_howie_ @IRC
GSF 600N 95/98 => 34Mm VFR 98/ => 119Mm "Blue-Eye"
Ein Motorrad ist dafür da um von A über B und C wieder nach A zu fahren und
das möglichst schnell um die Runde nochmal fahren zu können. c Simon Lenzen
Back to top
Jakob Bieling
Guest





PostPosted: Sat Nov 04, 2006 3:01 pm    Post subject: Re: selbst geschriebene Iteratoren Reply with quote

Boris Glawe wrote:


Quote:
Was habt ihr für Vorschläge, wie man am geschicktesten ausdrückt, dass
gerade ein Iterator eines leeren Containers dereferenziert wird. Ich

Letztendlich geht es nich um einen iterator eines leeren Containers,
sondern eher um einen iterator der auf das Element einem nach Letzten zeigt.
Dabei ist es (fast) egal, ob dein Container nun leer ist, oder nicht.

Bei einer vector-aehnlichen Datenstruktur hast du den end-iterator ja
quasi direkt (entweder 0, wenn kein Speicher alloziert wurde, oder eben ein
Element nach dem letzten im Array). Bei list-aehnlichen Datenstrukturen kann
man es eigentlich auch in dieser Art bauen. Der end-iterator ist immer ein
null-pointer. Wenn du also durch deine Liste hopst und ans Ende kommst (der
next-pointer der letzten Node ist ja ebenfalls null), dann wird dein
iterator beim inkrementieren ebenfalls auf null gesetzt, und entspricht
somit dem end-iterator.

hth
--
jb

(reply address in rot13, unscramble first)
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.