Löschen von einem dynamischen Array
-
Hallo,
kleine Frage zu meinem beispiel code
#include <iostream> using namespace std; int anzahl; double *messwerte = new double [anzahl]; void print() { for (int i= 0; i < anzahl; i++) cout << messwerte[i] << " "; } int main() { cout << "Anzahl der Messwerte eingeben:"; cin >> anzahl; for (int i = 0; i < anzahl; i++) { cout << "Naechsten Messwert eingeben: "; cin >> messwerte[i]; } print(); delete[]messwerte; cout << endl; print(); system("PAUSE"); return (0); }warum werden hier die messerwerte nicht mit dem "delete[]messwerte" gelöscht?
Ist fuer mich unerklärlich.
Freu mich auf eure Antworten.
danke
-
Woran erkennst du, dass sie nicht gelöscht werden?
-
Werden sie. Die Frage ist eher: Warum stuerzt dein Programm nicht ab? Ich sage einfach mal undefiniertes Verhalten.
-
Tippgeber schrieb:
Woran erkennst du, dass sie nicht gelöscht werden?
mit den der Konsolenausgabe
-------
wie ist die Lösung dieses Problem?
-
pampy schrieb:
Tippgeber schrieb:
Woran erkennst du, dass sie nicht gelöscht werden?
mit den der Konsolenausgabe
-------
wie ist die Lösung dieses Problem?
Es gibt kein Problem, abgesehen davon, dass du nach dem delete[] auf Speicher zugreifst der dir nicht mehr gehört. Wenn du dein Programm mit Debug-Informationen kompilierst, dann wird der Speicher je nach Compiler (und Einstellungen) beim Freigeben mit einem Muster wie 0xCDCDCDCD überschrieben, so kannst du leicht(er) erkennen wenn du auf ungültige Speicherbereiche zugreifst.
Mit einem Programm wie valgrind solltest du sowas übrigens auch leicht feststellen können.
-
Du darfst auf einen Speicherbereich nicht mehr zugreifen, nachdem du ihn mit delete freigegeben hast. Was passiert, wenn du es trotzdem versuchst, ist einfach undefiniert, wie schon gesagt wurde.
Betriebssysteme teilen den Speicher in Seiten auf, die z.B. eine Größe von 4 KB haben. Programme bekommen Speicher nur seitenweise zugeteilt. Der Effizienz wegen versucht man, mehrere kleine Objekte in eine Seite zu bekommen. Auch wenn du eines oder mehrere der Objekte in einer Seite wieder freigibst, kann die gesamte Seite erst wieder freigegeben werden, wenn auch das letzte Objekt in ihr freigegeben wurde. Was dann auch erklärt, warum du manchmal auf eigentlich schon gelöschte Objekte noch zugreifen kannst.const int n=10000000; const int s=100; int** m=new int*[n]; for (int i=0;i<n;i++)m[i]=new int; for (int i=0;i<n;i++)if (i%s!=0)delete m[i]; delete[] m;Das Beispiel verdeutlicht das noch ein wenig. Eigentlich werden 99% der 10 Millionen ints wieder freigegeben, trotzdem dürfte durch die Freigabe der Speicherverbrauch in den meisten Umgebungen nicht oder kaum sinken.
-
pampy schrieb:
#include <iostream> using namespace std; int anzahl; double *messwerte = new double [anzahl];Folgendes passiert hier:
anzahlundmesswertewerden statisch mit 0 initialisiert.messwertewird dynamisch mitnew double[anzahl]initialisiert.
- Die Ausführung von main startet und arbeitet auf einem Array mit 0 Elementen
"statisch initialisieren" == Initialisierung bevor überhaupt irgend etwas ausgeführt wird. Die Nullen sind schon da, kurz nachdem das Programm in den Speicher geladen wurde.
"dynamisch initialisieren" == Initialisierung beim Programmstart nach statischer Initialisierung und vor Ausführung von main.
void print() { for (int i= 0; i < anzahl; i++) cout << messwerte[i] << " ";Undefiniertes verhalten wenn Du
print()aufrufst undanzahl>0gilt. (Lesezugriff hinter dem reservierten Speicher)} int main() { cout << "Anzahl der Messwerte eingeben:"; cin >> anzahl; for (int i = 0; i < anzahl; i++) { cout << "Naechsten Messwert eingeben: "; cin >> messwerte[i];Undefiniertes Verhalten wenn
anzahl>0. (Lesezugriff hinter dem reservierten Speicher -> buffer overflow)warum werden hier die messerwerte nicht mit dem "delete[]messwerte" gelöscht?
Ist fuer mich unerklärlich.
Wie stellst Du das denn fest, dass sie nicht gelöscht werden?
Verbesserungstipp: Schmeiss
anzahlundmesswerteals "globale" Variablen aus Deinem Programm und nutze einenstd::vector<double>innerhalb Deiner main Funktion.int main() { int anzahl = 0; .... std::vector<double> messwerte; for (int i=0; i<anzahl; ++i) { double gelesen = ....; messwerte.push_back(gelesen); } .... }Gruß,
SP
-
danke fuer deine Antwort.
Ist das nur in C++ so ? Hat es dann nicht etwas mit "garbage collector" zu tun, den Java hat?
valgrind nur fuer linux?
-
pampy schrieb:
Ist das nur in C++ so ?
Nein.
Hat es dann nicht etwas mit "garbage collector" zu tun, den Java hat?
Nur entfernt.
valgrind nur fuer linux?
Für alle Unix-artigen Systeme, Windows zählt aber nicht dazu. Eine Alternative für Windows kenne ich nicht, aber irgendwas wird es da bestimmt geben.
-
pampy schrieb:
Ist das nur in C++ so ?
Was genau?
pampy schrieb:
Hat es dann nicht etwas mit "garbage collector" zu tun, den Java hat?
Ich weiß nicht, was Du meinst. Wie kommst Du denn darauf?
Gruß,
SP