Zeiger Frage
-
Warum ist das illegal? (Wird so in den Lösungen einer Aufgabe genannt)
vector<string> *pvec1 = new vector<string>(10); vector<string> *pv2 = pvec1; delete pv2;Darf ich nur über "pvec1" Speicher löschen, und nicht indirekt über pv2?
MfG
Stromberg
-
Stromberg schrieb:
Warum ist das illegal? (Wird so in den Lösungen einer Aufgabe genannt)
vector<string> *pvec1 = new vector<string>(10); vector<string> *pv2 = pvec1; delete pv2;Darf ich nur über "pvec1" Speicher löschen, und nicht indirekt über pv2?
MfG
StrombergEs ist nicht illegal, nur gefährlich. Wenn du den Speicher über pv2 löschst, so hast du 2 Zeiger pv2 und pvec1 auf denselben, nicht mehr gültigen Speicher. Das macht zwar noch nichts, aber wenn du nun an anderer Stelle in deinem Programm über pvec1 auf den Speicher zugreifen willst (du kannst ja nicht wissen, dass er gelöscht wurde...), dann hast du ein Problem

-
Aber wenn ich mir angewöhne nach dem Löschen ganz schnell "pv2 = NULL" zu verwenden, ist die ganze Situation ja entschärft?
MfG
Stromberg
-
Stromberg schrieb:
Aber wenn ich mir angewöhne nach dem Löschen ganz schnell "pv2 = NULL" zu verwenden, ist die ganze Situation ja entschärft?
MfG
StrombergNein, denn pvec1 bleibt ja bei seinem alten Wert, auch wenn du pv2 auf 0 setzt.
-
Guten Abend,
Ich beschäftige mich derzeit auch mit dynamischer Speicherverwaltung.
Wenn ich das richtig sehe, zeigt pvec1 auf die Anfangsadresse des vector.
Dann lässt du pv2 auf pvec1 zeigen.
Die Adresse auf die pv2 zeigt ist also gleich mit der Adresse auf die pvec1 zeigt.
Jetzt löscht du pv2.pvec1 zeigt aber immer noch auf die Adresse im Speicher.
Ich habe dazu folgenden Text gefunden:
Freigabe
Der Zeiger muss nicht der sein, mit dem der Speicher angefordert wurde. Er muss lediglich auf den richtigen Speicher zeigen und vom gleichen Typ sein. Nach der Speicherfreigabe durch delete empfiehlt es sich, die Zeigervariable auf 0 zu setzen. Damit wird verhindert, dass an einer anderen Stelle versehentlich eine weitere Freigabe erfolgt. delete erkennt, wenn die Zeigervariable 0 ist, und versucht dann erst gar nicht, dessen Speicher freizugeben. Fast noch wichtiger ist aber, dass eine weitere Verwendung dieses Zeigers zum Auslesen oder Beschreiben des Speichers sofort zu einem Fehler führt und damit auffindbar wird. Nach der Freigabe weist der Zeiger schließlich auf einen Speicherbereich, der nicht mehr gültig ist. Es kann sein, dass der Speicher später wieder vergeben wird. Wird der Zeiger nicht auf 0 gesetzt und arbeitet das Programm wieder mit diesem ungültigen Zeiger, wird Speicher verwendet, der vielleicht von anderen Programmteilen angefordert wurde. Da das Programm aber weiterläuft, als wäre alles in Ordnung, würde dieser Fehler nie gefunden.Aja->Quelle = http://www.willemer.de/informatik/cpp/dynamic.htm
Im Großen und Ganzen die ausführliche Variante meiner Threadvorgänger

-
44203215 schrieb:
Guten Abend,
Ich beschäftige mich derzeit auch mit dynamischer Speicherverwaltung.
Wenn ich das richtig sehe, zeigt pvec1 auf die Anfangsadresse des vector.
Dann lässt du pv2 auf pvec1 zeigen.
Die Adresse auf die pv2 zeigt ist also gleich mit der Adresse auf die pvec1 zeigt.
Jetzt löscht du pv2.pvec1 zeigt aber immer noch auf die Adresse im Speicher.
Nicht ganz. pvec1 zeigt in erster Linie auf den vector. Man kann dann noch einen Schritt weitergehen und überlegen, ob ein das auch wohl die Adresse des Anfangs des Speicherbereichs sein könnte. (ist es in dem Fall). Muss aber nicht bei allen Containern so sein.
Das gefährliche mit solchen Konstrukten ist halt, dass du durch übermüdeten Zustand mal irgendwo vergisst ein "= 0" zu machen und schon darfst du diese Unachtsamkeit ein paar Wochen/Jahre später mit einer Debugging Session büssen, weil du einen wilen Zeiger hast.
-
drakon schrieb:
Nicht ganz. pvec1 zeigt in erster Linie auf den vector. Man kann dann noch einen Schritt weitergehen und überlegen, ob ein das auch wohl die Adresse des Anfangs des Speicherbereichs sein könnte. (ist es in dem Fall). Muss aber nicht bei allen Containern so sein.
Die Adresse des Vektors wird nie die des Speicherbereichs sein.
Der Vektor holt sich den Speicher ja irgendwo dynamisch vom Heap.