Speicherverwaltung
-
Power Off schrieb:
Was auch ein Grund fuer Speicherlecks sein kann, ist, wenn Du bei std::vector vergisst, push_back() zu machen, um das Array zu vergroessern, bevor Du operator[] benutzt. Dann machst Du naemlich die Speicherliste kaputt.
Du solltest mal überlegen was du da eben von dir gegeben hast.
MfG
-
eViLiSSiMo schrieb:
Du solltest mal überlegen was du da eben von dir gegeben hast.
MfG
vector<T>::operator[] vergroessert ein Array nicht.
Laut Spezifikation liefert es eine Referenz auf ein Array-Element, der Index wird jedoch nicht auf Korrektheit geprueft, das macht vector<T>::at().
vector<T>::push_back() fuegt ein Element am Ende eines Array hinzu, und vergroessert es, wenn notwendig.
Die Speicherliste kann betroffen sein, wenn die Speicherverwaltung so funktioniert:
<pointer to next element> <size of memory block> ... data ... <pointer to next element> <size of memory block> ... data ...
Schreibt man ueber den Anfang oder das Ende eines Arrays hinaus, kann dadurch der Zeiger auf das naechste Element ueberschrieben werden.
Probier mal folgendes:
#include <vector> typedef std::vector<int> IntVec; int main( int argc, char** argv ) { IntVec v; v[-2] = 0XABCDEF01; v[-1] = 0X12345678; v[ 1] = 0X87654321; v[ 2] = 0XFEDCBA98; return 0; }
Das kann zu einem Absturz fuehren, wenn die Speicherliste keinen Platz rund um den zugewiesenen Speicher hat.
Es kann auch zu einem Speicherleck fuehren, wenn Zeiger der Speicherliste betroffen sind, oder das Laengenfeld im Speicherblock.
-
LOL Du Held.
Man füllt einen std::vector<> nicht mit dem operator[]
Laut Standard ist für den operator[] keinen Range check vorgeschrieben das heißt es gibt keine Exceptions und du kannst "einfach so" da machen was du willst.Die Methode at() hingegen muss schon einen range check machen.
C++ Standard 23.1.1 p 13 schrieb:
The member function at() provides boundschecked access to container elements. at() throws out_of_range if n >= a.size().
Und nun der oberhammer:
g++ 3.4.4 schrieb:
stdvec.cc: In function
int main(int, char**)': stdvec.cc:7: warning: passing negative value
-0x00000000000000002' for converting 1 oftypename \_Alloc::reference std::vector<\_Tp, \_Alloc>::operator[](size\_t) [with \_Tp = int, \_Alloc = std::allocator<int>]' stdvec.cc:8: warning: passing negative value
-0x00000000000000001' for converting 1 of `typename _Alloc::reference std::vector<_Tp, _Alloc>::operator[](size_t) [with _Tp = int, _Alloc = std::allocator<int>]'Das sollte mir zu denken geben. An deiner stelle würde ich mich mal genauer mit dem befassen. Anstatt hier einfach irgendwelche behauptungen auf zu stellen.
MfG
-
Ja ja, das sind aber nur Compiler-Warnungen, uebersetzt wird es trotzdem.
Und das mit dem operator[] habe ich ja bereits oben geschrieben:[quote=Power Off]
vector<T>::operator[] vergroessert ein Array nicht.Laut Spezifikation liefert es eine Referenz auf ein Array-Element, der Index wird jedoch nicht auf Korrektheit geprueft, das macht vector<T>::at().
[/quote]Lesen muesste man halt koennen, gell!
-
lol.
Hach ja
Lesen sollte man echt können.Ich hab die ganze Zeit gedacht du gehst davon aus das man mit dem op[] auch speicher allokieren könnte ^^
sry mein fehler
-
Danke schonmal für die motivierten Antworten soweit, zwei Fragen hab ich noch:
1. Sind Speicherlecks nur während der Ausführungszeit meines Codes relevant und
werden danach "von alleine" entfernt? z.B. vom Betriebssystem
2. Mir ist immer noch nicht klar, wie ich den smart-pointer dann verwende,
ohne dass mein Problem sich verschiebt und ich hinterher zusehen muss, dass
der pointer gelöscht wird. (das Objekt wird gelöscht, klar - aber der Zeiger?)
-
raphael2 schrieb:
1. Sind Speicherlecks nur während der Ausführungszeit meines Codes relevant und
werden danach "von alleine" entfernt? z.B. vom Betriebssystemjo, das os gibt alles wieder frei wenn dein programm nicht mehr läuft
-
Chew-Z schrieb:
1.) Verlassen auto_ptr den Gültigkeitsbereich wird der delete für den Pointer
aufgerufen. Grade das ist ja der Trick. Das heisst, du machst igendwann dein
new und der auto_ptr macht das zugehörige delete.
2.) auto_ptr vetragen sich NICHT mit STL-Containern, wegen der Besonderheiten
bezüglich "Copy" und "Assignment". Daher KEINE auto_ptr in STL-Containern
verwenden. Willst du Smart-Pointer in STL-Containern, dann verwendest
du am besten was von boost.Wer lesen kan ist klar im Vorteil.
Siehe Punkt 1
-
Bin evtl. etwas langsam, aber jetzt erkläre ich meine Frage nochmal, vielleicht kapier ichs ja noch:
Ich habe also diese Methode, die für mich rechnet:
static set<int> *berechnung(vector<vector<int> > *data){ set<int> *erg = new set<int>; //rechnen return erg;
dann habe ich eine Schleife, die diese Methode aufruft, bis keine
neuen Ergebnisse mehr geliefert werden:vector<vector<int> > *myData; //myData wird initialisiert und gefüllt while(unfinished()){ mySet.insert(berechnung(myData) }
Jetzt wurde vorgeschlagen, ich gebe anstatt dessen einen auto_pointer
zurück, meine Methode muss doch aber trotzdem diesen autopointer mit
new initialisieren, ungefähr so:auto_prt<set<int> berechnung{ auto_ptr<set<int> > ret( new set<int> ); //berechnung... return ret; }
damit ist der auto_ptr nach Rückgabe schon nichtmehr gültig.
Anders müsste ich ihn mit new erstellen:... auto_ptr<set<int> > ret = *(new auto_ptr<set<int> >(new set<int>)); //berechnung... return ret
und jetzt habe ich vielleicht ein kleineres Speicherleck (nur ein Pointer)
aber das kann ja nicht die Idee sein.Danke soweit.
-
Ich habe eine Webpage gefunden, die den Mechanismus unterschiedlicher Besitzer bei auto-pointern erklärt und damit hat sich auch die Frage erledigt.
Grüße, Raphael