Pointer *it Speicherleck?
-
Hallo,
s. Code untenstehend
for(auto it = items.begin(); it != items.end(); ++it){ map <string, string> hunt; string url = *it; hunt["url"] = url; hunt["short"] = BIN[url]["short"]; links.push_back(hunt); }Muss ich den Pointer *it explizit freigeben (delete) oder passiert das automatisch?
c++ 201402MFG
-
Du meinst den
stringurl... aber das passiert alles automatisch.
-
it ist kein Pointer, sondern ein Iterator.
-
-
@_ro_ro Was von
begin/endzurückgegeben wird sind entweder spezielle Iterator-Objekte oder maximal nicht-besitzende Pointer. Beides muss man nicht explizit freigeben.
-
@_ro_ro
Ja, ein Iterator ist kein Pointer.
-
@Finnegan sagte in Pointer *it Speicherleck?:
@_ro_ro Was von
begin/endzurückgegeben wird sind entweder spezielle Iterator-Objekte oder maximal nicht-besitzende Pointer. Beides muss man nicht explizit freigeben.OK, danke. Hab' mittlerweile auch begriffen, daß ich den Iterator gar nicht brauche weil ich mit
auto item:itemsden Wert direkt bekomme. Mächtig gewaltig c++ mal sehen wie das weitergeht
Danke Euch!!!
-
@_ro_ro sagte in Pointer *it Speicherleck?:
ist ein iterator kein Pointer?
Nein. diese verhalten sich nur ähnlich wie Zeiger, besonders was Dereferenzieren und Zugriff auf benachbarte Elemente angeht. Das ist so gewollt, dass die ähnlich zu benutzen sind. Man könnte sogar eine Container-Klasse bauen, die für
begin/endPointer zurückgibt, wenn die zugrundeliegende Datenstruktur es erlaubt, dass man die Elemente einfach über Pointer-Arithmetik iteriert. Ich glaube aber nicht, dass das eine Implemetierung der Standardbibliothek so macht, obwohl ich mir vorstellen kann, dass das z.B. beistd::array,std::vectorundstd::stringmöglich wäre. Iteratoren können durchaus Pointer sein, aber im Allgemeinen stimmt das natürlich nicht.Edit: GCC (bzw. hier libstdc++, die Standardbibliothek von GCC) scheint für
std::arraytatsächlich mit Pointern als Iteratoren zu arbeiten: https://godbolt.org/z/fjd6n7z71.Piin der Ausgabe steht hier fürint*(Stichwort "Name Mangling").
-
@Finnegan sagte in Pointer *it Speicherleck?:
dass man die Elemente einfach über Pointer-Arithmetik iteriert. Ich glaube aber nicht, dass das eine Implemetierung der Standardbibliothek so macht, obwohl ich mir vorstellen kann, dass das z.B. bei std::array, std::vector und std::string möglich wäre.
MIr ist da eine Sache für
std::vectoroderstd::stringaufgefallen.Nehmen wir an, ein Iterator wäre als Pointer implementiert. Und nehmen wir ferner an, wir nutzen den Iterator in der Form:
std::vector<int> vec{1, 2, 3, 4}; auto it = vec.begin(); while(it != vec.end()) { if (Foo(it)) vec.push_back(5); //... it++; }Dann würde der Code abstürzen, wenn
vec.push_back(5);oft aufgerufen wird. In diesem Fall allokiert nämlichstd::vectorneuen Speicher, kopiert die alten Daten in den neuen Speicher und löscht den alten Speicher. Dadurch würde der Iterator ungültig und der Iterator-Pointer zeigt auf Datenmüll.Deswegen, so schätze ich, macht ein Index bei Random Access Iteratoren mehr Sinn.
-
@Quiche-Lorraine sagte in Pointer *it Speicherleck?:
Dann würde der Code abstürzen, wenn
vec.push_back(5);oft aufgerufen wird. In diesem Fall allokiert nämlichstd::vectorneuen Speicher, kopiert die alten Daten in den neuen Speicher und löscht den alten Speicher. Dadurch würde der Iterator ungültig und der Iterator-Pointer zeigt auf Datenmüll.Deswegen, so schätze ich, macht ein Index bei Random Access Iteratoren mehr Sinn.
Ja, ich denke sowas kann man mit speziellen Iterator-Klassen flexibler umsetzen, so dass diese auch bei solchen Operationen weiterhin gültig bleiben. Allerdings invalidiert ein
vector::push_backexistierende Referenzen und Pointer in diesem Fall - das ist also hier UB:If after the operation the new size() is greater than old capacity() a reallocation takes place, in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Otherwise only the end() iterator is invalidated.
https://en.cppreference.com/w/cpp/container/vector/push_back
Das dürfte auch so im Standard stehen. Ich denke aber, man könnte mit Iterator-Objekten durchaus eine vector-Klasse implementieren, welche die Iterator-Gültigkeit auch bei Reallokation garantiert.