 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Michael Schuster Guest
|
Posted: Thu Mar 17, 2005 5:02 pm Post subject: Referenz std::vector |
|
|
Hallo,
ich steh vor folgender Frage, die ich mal nur so in Pseudocode
formulieren will:
Angenommen ich hätte sowas wie
std::vector < std::vector< Typ> > VListe
wobei Typ ein C++ Objekt darstellt.
Wenn ich nun Vliste vergößere mit
std::vector<Typ> k (sei bekannt)
VListe.push_back(k);
und dann schreibe:
Typ* o=VListe[0][0] (vorausgesetzt element existiert)
ist dann o immer ein gültiger Zeiger auf dieses Element(0,0) oder darf
sich die Allokation von VListe[0] verändern? Beispielsweise, wenn ich
danach ausführe:
std::vector<Typ> p (sei bekannt)
VListe.push_back(p); (nun ist also p und k in VListe)
Ist o noch gültig auf Element (0,0) oder ist nun
o!= VListe[0][0] ??
wie wäre es bei std::map<int, < std::vector< Typ> > VListe?
Danke für Eure Hilfe schon mal im voraus
Michael
--
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 |
|
 |
Albrecht Fritzsche Guest
|
Posted: Thu Mar 17, 2005 6:20 pm Post subject: Re: Referenz std::vector |
|
|
Michael Schuster wrote:
| Quote: | Hallo,
ich steh vor folgender Frage, die ich mal nur so in Pseudocode
formulieren will:
Angenommen ich hätte sowas wie
std::vector < std::vector< Typ> > VListe
wobei Typ ein C++ Objekt darstellt.
Wenn ich nun Vliste vergößere mit
std::vector<Typ> k (sei bekannt)
VListe.push_back(k);
und dann schreibe:
Typ* o=VListe[0][0] (vorausgesetzt element existiert)
|
Wuerde nicht kompilieren - aber Referenzen wie auch Iteratoren
in vector werden durch die non-const-Memberfunktionen ungueltig.
std::list verhaelt sich da zB anders, aber bei vectors empfielt
es sich daher eher, den Index als "Referenz" aufzuheben.
Ali
--
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 |
|
 |
Rolf Magnus Guest
|
Posted: Thu Mar 17, 2005 6:46 pm Post subject: Re: Referenz std::vector |
|
|
Michael Schuster wrote:
| Quote: | Hallo,
ich steh vor folgender Frage, die ich mal nur so in Pseudocode
formulieren will:
Angenommen ich hätte sowas wie
std::vector < std::vector< Typ> > VListe
wobei Typ ein C++ Objekt darstellt.
Wenn ich nun Vliste vergößere mit
std::vector<Typ> k (sei bekannt)
VListe.push_back(k);
und dann schreibe:
Typ* o=VListe[0][0] (vorausgesetzt element existiert)
|
Das sollte nicht funktionieren, denn VListe[0][0] ist eine Referenz auf Typ,
kein Zeiger.
| Quote: | ist dann o immer ein gültiger Zeiger auf dieses Element(0,0) oder darf
sich die Allokation von VListe[0] verändern? Beispielsweise, wenn ich
danach ausführe:
std::vector<Typ> p (sei bekannt)
VListe.push_back(p); (nun ist also p und k in VListe)
Ist o noch gültig auf Element (0,0) oder ist nun
o!= VListe[0][0] ??
|
Je nach dem, ob der Vektor eine Reallokation macht, was prinzipell bedeutet,
daß du davon ausgehen mußt, daß es nicht mehr gültig ist, es sei denn, du
schaffst schon vorher genug Platz im Vektor, damit er nicht mehr
reallokieren muß.
| Quote: | wie wäre es bei std::map<int, < std::vector< Typ> > VListe?
|
Meines Wissens würde es da gültig bleiben, bis das Element wieder gelöscht
wird. Aber ganz sicher bin ich mir da nicht.
--
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 |
|
 |
Michi Guest
|
Posted: Fri Mar 18, 2005 9:18 am Post subject: Re: Referenz std::vector |
|
|
Rolf Magnus wrote:
| Quote: | Michael Schuster wrote:
Je nach dem, ob der Vektor eine Reallokation macht, was prinzipell
bedeutet,
daß du davon ausgehen mußt, daß es nicht mehr gültig ist, es sei
denn, du
schaffst schon vorher genug Platz im Vektor, damit er nicht mehr
reallokieren muß.
|
Ja, reallokieren wird der Vektor sicher nicht.
(Anmerkung: es muss natürlich Typ* o=&VListe[0][0] heissen)
| Quote: | wie wäre es bei std::map<int, < std::vector< Typ> > VListe?
Meines Wissens würde es da gültig bleiben, bis das Element wieder
gelöscht
wird. Aber ganz sicher bin ich mir da nicht.
|
Hm....
Michael
--
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 Mang Guest
|
Posted: Tue Mar 22, 2005 6:18 am Post subject: Re: Referenz std::vector |
|
|
"Michael Schuster" <michi (AT) flyflaps (DOT) de> schrieb im Newsbeitrag
news:f6742f8c.0503170902.28dd7163 (AT) posting (DOT) google.com...
| Quote: | Hallo,
ich steh vor folgender Frage, die ich mal nur so in Pseudocode
formulieren will:
Angenommen ich hätte sowas wie
std::vector < std::vector< Typ> > VListe
wobei Typ ein C++ Objekt darstellt.
Wenn ich nun Vliste vergößere mit
std::vector<Typ> k (sei bekannt)
VListe.push_back(k);
und dann schreibe:
Typ* o=VListe[0][0] (vorausgesetzt element existiert)
ist dann o immer ein gültiger Zeiger auf dieses Element(0,0) oder darf
sich die Allokation von VListe[0] verändern? Beispielsweise, wenn ich
danach ausführe:
std::vector<Typ> p (sei bekannt)
VListe.push_back(p); (nun ist also p und k in VListe)
Ist o noch gültig auf Element (0,0) oder ist nun
o!= VListe[0][0] ??
|
Gute Frage. Sogar sehr gute Frage.
Zuerst einmal das Konzept vom Standard: Einfügen / Löschen von Elementen
kann Iteratoren auf diese Elemente invalidieren, unter bestimmten Umständen.
Für Einfügeoperationen bleiben nur jene Iteratoren gültig, die vor dem
eingefügten Element lagen, UND wenn insgesamt keine Neualloziierung von
Speicher stattfand (also capacity() - size() >= Anzahl an einzufügenden
Elementen). Erase und Äquivalente invalidiert alles hinter dem zu löschenden
Element.
Soviel zu Iteratoren. Nun hast Du aber Zeiger, und die sind was anderes. Die
Frage, die ich mir stelle ist ob die Garantien für Iteratoren auch für
Zeiger gelten. Meiner Meinung nach bei einer (strikten) Interpretation
nicht.
Anders ausgedrückt: Nehmen wir an der Kopierkonstruktor wirft im
Zweifelsfall nicht. Ist ein vector, der die physischen Adressen der
verwalteten Objekte während const-Funktionen (oder einfach nur so während
der Laufzeit) ändert, in irgendeiner Weise verboten (aber Iteratoren nicht
invalidiert - z.B. weil die einen Zeiger auf Ihren Container speichern)? In
anderen Worten, ist dieses Programm sicher definiert:
std::vector<int> v(10);
int* i = &v[0];
v.size();
assert(i == &v[0]);
?? Oder ist das möglicherweise undefiniertes Verhalten, falls i ins
Niemandsland zeigt (beid der r-value Konvertierung), weil v intern
rumgeschaufelt hat?
Ich habe ehrlich gesagt im Standard auf die Schnelle nichts gefunden, daß
obiges Progrämmchen garantiert. Deshalb Deine meiner Meinung nach sehr gute
Frage.
Praktisch ist das sicher mehr definierter als vieles andere was laut
Standard "funktionieren" sollte......
| Quote: |
wie wäre es bei std::map<int, < std::vector< Typ> > VListe?
|
Theoretisch selbes Problem wie oben. Bezüglich Iteratorengarantien hat man
es einfacher - node-basierte Container (die assoziativen + list)
invalidieren Iteratoren auf Elemente weder bei Einfüge- noch bei
Löschoperationen (es sei denn, das Element auf das der Iterator zeigt wird
gelöscht...). In der Tat ist das praktisch eines der Hauptargumente, eine
std::list zu verwenden, und keinen vector.
Thomas
--
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 |
|
 |
Edzard Egberts Guest
|
Posted: Tue Mar 22, 2005 12:08 pm Post subject: Re: Referenz std::vector |
|
|
Hallo Michael,
| Quote: | Wenn ich nun Vliste vergößere mit
std::vector<Typ> k (sei bekannt)
VListe.push_back(k);
und dann schreibe:
Typ* o=VListe[0][0] (vorausgesetzt element existiert)
ist dann o immer ein gültiger Zeiger auf dieses Element(0,0) oder darf
sich die Allokation von VListe[0] verändern?
|
die Allokation darf sich verändern - ein Vector kann sich beim Einfügen
eines Elementes jederzeit komplett neu anlegen.
Meines Erachtens ist Deine Vorgehensweise aber grundsätzlich falsch -
ein Vector ist speziell dafür gedacht, dass auf die Elemente über den
Index zugegriffen wird. Wenn Du statt dessen unbedingt einen Zeiger
verwenden willst - selber Schuld!
Damit Zeiger gültig bleiben, mußt Du eben einen anderen Container
nehmen, der besser für Iterator-/Zeigerzugriff geeignet ist. Übrigens
steht AFAIk in der Doku zu STL-Containern immer genau, wie die sich beim
Einfügen und Löschen von Elementen verhalten - im Zweifelsfall also an
der Quelle nachlesen.
Gruß,
Ed
--
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 |
|
 |
Albrecht Fritzsche Guest
|
Posted: Tue Mar 22, 2005 9:35 pm Post subject: Re: Referenz std::vector |
|
|
Thomas Mang wrote:
| Quote: |
Soviel zu Iteratoren. Nun hast Du aber Zeiger, und die sind was anderes. Die
Frage, die ich mir stelle ist ob die Garantien für Iteratoren auch für
Zeiger gelten.
|
Nein, da gelten nicht unbedingt die gleichen - aber der Standard fuehrt
beide explizit auf (genauer, Iteratoren und Referenzen). Unterschiede
gibt's zB bei deque, wo ein Einfuegen am Anfang bzw. Ende nur die
Iteratoren ungueltig macht, nicht aber die Referenzen.
| Quote: | std::vector<int> v(10);
int* i = &v[0];
v.size();
assert(i == &v[0]);
|
Warum nicht - vector::size() macht weder die Iteratoren nocht die
Referenzen ungueltig.
Ali
--
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 |
|
 |
Michi Guest
|
Posted: Wed Mar 23, 2005 8:52 am Post subject: Re: Referenz std::vector |
|
|
Albrecht Fritzsche wrote:
| Quote: | Thomas Mang wrote:
Warum nicht - vector::size() macht weder die Iteratoren nocht die
Referenzen ungueltig.
|
Wenn ich nun schreibe:
Typ* o= new Typ[100];
std::vector<Typ*> v;
v.push_back(o)
Typ* i = &v[0][0];
dann müsste wohl alles im grünen Bereich liegen?
Michael
--
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 |
|
 |
Albrecht Fritzsche Guest
|
Posted: Wed Mar 23, 2005 6:14 pm Post subject: Re: Referenz std::vector |
|
|
Michi wrote:
| Quote: | Albrecht Fritzsche wrote:
Thomas Mang wrote:
Warum nicht - vector::size() macht weder die Iteratoren nocht die
Referenzen ungueltig.
Wenn ich nun schreibe:
Typ* o= new Typ[100];
std::vector<Typ*> v;
v.push_back(o)
Typ* i = &v[0][0];
dann müsste wohl alles im grünen Bereich liegen?
|
Leider ja Ich wuerde allerdings reinen C++-Code bevorzugen,
um Memory Leaks etc gleich von vornherein zu vermeiden.
Ali
--
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 |
|
 |
Michi Guest
|
Posted: Tue Mar 29, 2005 1:13 pm Post subject: Re: Referenz std::vector |
|
|
| Quote: | Leider ja Ich wuerde allerdings reinen C++-Code bevorzugen,
um Memory Leaks etc gleich von vornherein zu vermeiden.
Die Obekte werden während der gesamten Laufzeit nicht mehr destruiert. |
Können dann hier diese entstehen ?
Michael
--
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 |
|
 |
Albrecht Fritzsche Guest
|
Posted: Thu Mar 31, 2005 5:32 pm Post subject: Re: Referenz std::vector |
|
|
Michi wrote:
| Quote: | Leider ja Ich wuerde allerdings reinen C++-Code bevorzugen,
um Memory Leaks etc gleich von vornherein zu vermeiden.
Die Obekte werden während der gesamten Laufzeit nicht mehr destruiert.
|
Wenn man Code wiederverwendbar bzw von verschiedenen Stellen aus
aufrufbar schreiben moechte, sollte man sich vor solchen Aussagen
hueten - zudem Objekte immer, wenn sie ausser Scope geraten, zerstoert
werden sollten.
Zudem ist die Frage, warum Du ueberhaupt die Objekte dynamisch
erzeugst und nicht, wie ja eigentlich naheliegender, auf dem Stack.
Ali
--
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
|
|