C++ Ist es notwendig Zeiger zu löschen?

T

Tersus

Gast
Guten Abend Leute,

wie ich den mit new reservierten Speicher wieder freigebe, ist mir klar. Nur der Sinn dahinter nicht so ganz.

Code:
int* ptr = new int;
*ptr = 5;

cout << *ptr << endl; // 5
delete ptr;
cout << *ptr << endl; // 0

So wie das hier ausschaut, hat delete lediglich in die Speicherzelle, auf die ptr zeigt, eine 0 rein geschrieben.
a) Könnte man da auch selbst eine 0 reinschreiben
b) Was unterscheidet die 0 in dieser Speicherzelle von einem andere Integer?
c) Der Zeiger selbst belegt ja auch Speicher. Ist es nötig, ja gar möglich, den Speicher, den der Zeiger ptr benötigt, frei zu geben?
 
Es ist nicht garantiert, worauf der Pointer nach dem delete zeigt und dementsprechend auch nicht was dessen Wert ist. Manchmal wird noch etwas ausgegeben wie bei dir, manchmal wird sich dein Programm mit einem Speicherzugriffsfehler verabschieden.
Es ist allerdings die Regel, dass ein Pointer, nachdem er gelöscht wurde, mit 0 belegt wird. Aber eben der Pointer selbst und nicht dessen Wert. So lassen sich gelöschte bzw. wieder freie Pointer abfragen.

a) Ja, aber dann hast du ein Speicherleck erzeugt, denn der Speicher auf den der Pointer gezeigt hat, wird nie wieder freigegeben.
b) Die 0 in deinem Beispiel ist einfach nur der Wert der Adresse auf die der Pointer nach dem Löschen zeigt.
c) Nein, der Pointer selbst liegt auf dem Stack.
 
Zuletzt bearbeitet:
Oder nach dem Dangling Pointer Problem.

Das ist der Grund, warum man keine Zeiger mehr verwenden sollte.
 
Ich korrigiere mal den Kommentar im Codebeispiel:

Tersus schrieb:
Code:
cout << *ptr << endl; // 5
delete ptr;
cout << *ptr << endl; // Undefiniertes Verhalten

Das Programm könnte genau so gut mit einem Segmentation Fault abstürzen, wenn die entsprechende RAM-Seite nicht mehr dem Prozess gehört. Du greifst auf Speicher zu, auf den du nicht mehr zugreifen solltest - mach das Gleiche mal mit einem großen Array und versuche dann noch, auf die einzelnen Elemente zuzugreifen ;)

Deswegen mag ich Rust irgendwie, da meckert der Compiler, wenn man sowas versucht.

Das ist der Grund, warum man keine Zeiger mehr verwenden sollte.
Zumindest keine nackten Zeiger auf C++-Objekte.
 
Der Pointer an sich, schreibt er doch.
Code:
int* ptr = 0;

ptr brauchst du nicht löschen, der ist auf dem Stack abgelegt, genauso wenig wie du ein einfaches
Code:
int num = 5;
nicht löschen brauchst.

Oder ist etwas anderes gemeint?
 
VikingGe schrieb:
Ich korrigiere mal den Kommentar im Codebeispiel:



Das Programm könnte genau so gut mit einem Segmentation Fault abstürzen, wenn die entsprechende RAM-Seite nicht mehr dem Prozess gehört. Du greifst auf Speicher zu, auf den du nicht mehr zugreifen solltest - mach das Gleiche mal mit einem großen Array und versuche dann noch, auf die einzelnen Elemente zuzugreifen ;)

Deswegen mag ich Rust irgendwie, da meckert der Compiler, wenn man sowas versucht.


Zumindest keine nackten Zeiger auf C++-Objekte.

Rust besitzt genau wie C++ Raw Pointer und sobald diese benutzt werden gibt es eben so wie bei C++ für nichts eine Garantie.
https://doc.rust-lang.org/book/raw-pointers.html
Raw Pointer sollte man in Modern C++ ebenfalls nicht mehr nutzen(lässt sich aber natürlich nicht immer verhindern)
 
Mit dem Unterschied, dass man bei Rust explizit unsafe hinschreiben muss, was im Gegensatz zu einem falsch platzierten delete nicht mal eben so versehentlich passiert.

Smart Pointer in C++ lösen jedenfalls die meisten Probleme, aber auch damit kann man noch Mist bauen:

Code:
auto a = std::make_unique<int>(5);
auto b = std::move(a);
*a = 2;  // oops

Nicht ganz so dramatisch wie der Fehler im Eröffnungspost, weil das ganze in der Praxis in der Regel in einer Nullpointer-Dereferenzierung und nem Segfault resultiert und das Szenario gleichzeitig auch eher selten auftreten dürfte, achten muss man auf sowas trotzdem.
 
DaysShadow schrieb:
Der Pointer an sich, schreibt er doch.
Code:
int* ptr = 0;

ptr brauchst du nicht löschen, der ist auf dem Stack abgelegt, genauso wenig wie du ein einfaches
Code:
int num = 5;
nicht löschen brauchst.

Oder ist etwas anderes gemeint?

Vielen Dank! :)

Ein Danke auch an all die anderen. Viel Interessantes.
 
Zurück
Oben