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
string
url
... aber das passiert alles automatisch.
-
it ist kein Pointer, sondern ein Iterator.
-
-
@_ro_ro Was von
begin
/end
zurü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
/end
zurü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:items
den Wert direkt bekomme. Mächtig gewaltig c++ mal sehen wie das weitergehtDanke 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
/end
Pointer 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::vector
undstd::string
mö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::array
tatsächlich mit Pointern als Iteratoren zu arbeiten: https://godbolt.org/z/fjd6n7z71.Pi
in 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::vector
oderstd::string
aufgefallen.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::vector
neuen 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::vector
neuen 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_back
existierende 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.