2010-05-07 20 views
6

Ich habe einen Zeiger, der auf ein Array zeigt, und einen anderen Zeiger, der auf dasselbe Array verweist. Wie lösche ich einen dieser Zeiger, ohne das Array zu löschen, so dass der zweite nicht gelöschte Zeiger immer noch funktioniert?Wie löscht man einen Zeiger, ohne die Daten zu löschen, auf die der Zeiger zeigt?

zum Beispiel:

int* pointer1 = new int [1000]; 
int* pointer2; 
pointer2 = pointer1; 

Jetzt möchte ich von Zeiger1 loszuwerden, wie würde ich es tun, so dass ich auch weiterhin das Array normaly durch Zeiger2 zugreifen?

Antwort

10

Diese Zeiger sind auf dem Stapel; Sie müssen sie nicht löschen. Ignorieren Sie einfach pointer1 und es wird am Ende des Blocks weggehen.

+1

Ahh das erklärt es das Beste für mich. Ein Zeiger ist also einfach eine Variable auf dem Stack, das macht Sinn. Dies bedeutet, dass es nicht außerhalb des Geltungsbereichs zugegriffen werden kann und ich es nicht versehentlich außerhalb des Geltungsbereichs verwenden werde und Probleme verursachen. OK danke. – Faken

+2

@ Faken - Um klar zu sein, "ein Zeiger ist einfach eine Variable auf dem Stapel" ist keine wahre Aussage. Der Zeiger in Ihrem Codebeispiel ist eine Stapelvariable, da Sie es statisch deklariert haben. Ein Zeiger kann auch dynamisch deklariert werden, wie Neil Butterworth in seinem Beispiel zeigt. Es ist alles, wie Sie es deklarieren, es ist nichts Besonderes, dass das Objekt ein Zeiger ist. – bta

+3

@bta: Ich sehe nichts statisch erklärt. Vielleicht meinen Sie "automatisch", den eigentlichen Begriff. (Das heißt, Dinge sind nicht stapelweise zugeordnet, aber sie werden automatisch zugewiesen.) – GManNickG

9

Lassen Sie es außerhalb des Geltungsbereichs gehen?

Sie "löschen" Zeiger nicht, Sie löschen, was sie zeigen. Wenn Sie also nur die Variable 'pointer1' loswerden wollen, müssen Sie nur den Bereich beenden, in dem sie erstellt wurde.

9

Sie übergeben diesen Zeiger überhaupt nicht an delete. Du hörst einfach auf, diesen Zeiger zu benutzen. Wenn Sie sicherstellen möchten, dass Sie nicht erneut über diesen Zeiger auf das Array zugreifen, können Sie es auf null setzen.

C und C++ verfolgen nicht, wie viele Zeiger auf ein Objekt oder ein Array zeigen. Wenn Sie eine Referenzzählung durchführen möchten, müssen Sie einen Container mit Referenzzählung verwenden, z. B. shared_ptr oder in diesem Fall shared_array (Sie finden beide in Boost und es gibt eine hohe Wahrscheinlichkeit, dass Ihre Implementierung sie bereits in <memory> entweder in der std Namensraum oder in std::tr1).

1
int** pointer1 = new int *; 
* pointer1 = new int [1000]; 
int* pointer2; 
pointer2 = * pointer1; 
delete pointer1; 
+0

Heh, du warst mir in der Vergangenheit sehr hilfsbereit, aber dieses Mal hast du mich nur verwirrt, heh. – Faken

+2

@Faken Betrachte es als eine Zen-Lektion: Grundsätzlich, wie andere schon gesagt haben, macht deine Frage keinen Sinn. –

+0

@ Faken- Er zeigt Ihnen, was Sie tun müssten, wenn Sie den Zeiger löschen möchten. Er erstellt einen "Zeiger auf einen Zeiger" und weist ihm die Adresse eines durch "neu" erstellten "int *" zu. Da 'pointer1' in diesem Fall dynamisch zugewiesen wird, können Sie es" freigeben ", sobald Sie damit fertig sind. Die Komplexität dieser Lösung weist wahrscheinlich darauf hin, dass Sie neu überdenken müssen, ob Sie den Zeiger wirklich löschen müssen. – bta

3

Es ist eine Stapelgröße (wie Sie es geschrieben haben) und damit auf den Bereich, den Sie es in deklariert gebunden. Sobald Sie die schließende geschweifte Klammer dieses bestimmten Umfang getroffen, wird es ohne dich aufgeräumt erhalten etwas dagegen tun müssen.

Wenn Sie absolut sicher gehen wollen, dass nichts mehr Zeiger1 mehr verwenden kann, können Sie pointer1=NULL einstellen, sobald Sie damit fertig sind.

4

Wenn Sie einen Zeiger mit int* pointer1; statisch deklarieren, können Sie ihn nicht freigeben. Sie können nur den dynamisch zugewiesenen Speicher freigeben, den Sie mit new, malloc usw. zugewiesen haben. Die einzige Möglichkeit, "pointer1" loszuwerden, besteht darin, den Gültigkeitsbereich des Bereichs zu verlassen, z. Wenn Sie mit pointer1 fertig sind und verhindern möchten, dass das Array versehentlich geändert wird, verwenden Sie pointer1 = NULL;.

1

Ignorieren Sie einfach den Zeiger, und er wird verschwinden, wenn Sie mit Ihrer Funktion oder Blockierung fertig sind. Denken Sie daran, dass kein Zugriff mehr möglich ist, wenn Sie keinen Zeiger mehr auf etwas haben. Natürlich wird es immer noch Speicherplatz verbrauchen, aber Sie werden nicht dazu in der Lage sein. Bevor Sie also in Erwägung ziehen, den Zeiger loszulassen, stellen Sie sicher, dass Sie irgendwo einen anderen Zeiger darauf haben, oder Sie werden ihn los.

4

Normalerweise, um einen Zeiger "sicher" zu machen, setzen Sie ihn einfach auf NULL, wodurch er auf nichts zeigt. Oder Sie können es einfach außer Reichweite lassen.

Zum Beispiel, wenn Sie zwei Zeiger haben.

int *a = new int; 
int *b = a; 

// somewhere  
b = NULL; 

delete b; // does nothing now 
delete a; // deletes a 

Oder Sie können es aus dem Anwendungsbereich fallen lassen.

int *a = new int; 

{ 
int *b = a; 
// blah blah blah 
} 

// don't have to worry about b 
delete a; 
+0

Ist 'b = NULL; löschen b' etwas tun? Ist es definiert? Ich hatte den Eindruck, dass das eine Art Bug oder undefiniertes Verhalten ist. –

+0

@Nathan: 'foo = NULL; delete foo; 'ist genau legal und harmlos. Bedeutet, dass Sie nicht immer vor dem Löschen nach Nicht-NULL-Werten suchen müssen. –

Verwandte Themen