2010-05-07 16 views
6

Ho un puntatore che punta a una matrice ea un altro puntatore che fa riferimento alla stessa matrice. Come posso eliminare uno di questi puntatori senza uccidere l'array in modo che il secondo puntatore non cancellato funzioni ancora?Come si elimina un puntatore senza eliminare i dati a cui punta il puntatore?

ad esempio:

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

Ora voglio sbarazzarsi di Puntatore1, come potrei farlo in modo tale che io possa continuare ad accedere alla matrice normalmente attraverso pointer2?

risposta

10

Questi puntatori sono in pila; non devi eliminarli. Ignora semplicemente pointer1 e andrà via alla fine del blocco.

+1

Ah, questo mi spiega il meglio per me. Quindi un puntatore è semplicemente una variabile in pila, questo ha senso. Questo significa che non è possibile accedervi al di fuori del campo di applicazione e che non lo utilizzerò accidentalmente fuori dal campo di applicazione e causerà problemi. Ok grazie. – Faken

+2

@ Faken Per essere chiari, "un puntatore è semplicemente una variabile sullo stack" non è una dichiarazione vera. Il puntatore nell'esempio di codice è una variabile stack perché lo hai dichiarato staticamente. Un puntatore può anche essere dichiarato dinamicamente, come Neil Butterworth mostra nel suo esempio. È tutto nel modo in cui lo si dichiara, non c'è niente di speciale nell'essere un puntatore. – bta

+3

@bta: non vedo nulla dichiarato staticamente. Forse intendi "automatico", il vero termine. (Ovvero, le cose non sono allocate allo stack, ma vengono allocate automaticamente.) – GManNickG

9

Lasciare fuori portata?

Non si eliminano i puntatori, si elimina ciò a cui puntano. Quindi, se vuoi semplicemente sbarazzarti della variabile 'pointer1', l'unico modo per farlo è che l'ambito in cui è stato creato sia terminato.

9

Non si passa il puntatore a delete. Basta smettere di usare quel puntatore. Se vuoi assicurarti di non accedere nuovamente alla matrice attraverso quel puntatore, puoi impostarla su null.

C e C++ non tengono traccia di quanti puntatori puntano a un oggetto oa un array. Se si desidera il conteggio dei riferimenti, è necessario utilizzare un contenitore conteggiato con riferimento, ad esempio shared_ptr o, in questo caso, shared_array (è possibile trovarne entrambi in Boost ed è molto probabile che la propria implementazione li abbia già in <memory> in lo spazio dei nomi std o std::tr1).

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

Heh, mi sei stato di grande aiuto in passato, ma questa volta mi hai semplicemente confuso, eh. – Faken

+2

@Faken Considera una lezione Zen :-) Fondamentalmente, come altri hanno sottolineato, la tua domanda non ha molto senso. –

+0

@ Faken - Ti sta mostrando cosa avresti dovuto fare se volessi essere in grado di eliminare il puntatore. Crea un "pointer-to-a-pointer" e gli assegna l'indirizzo di un 'int *' creato tramite 'new'. Dato che 'pointer1' è assegnato dinamicamente in questo caso, puoi" liberarlo "una volta che hai finito con esso. La complessità di questa soluzione indica probabilmente che è necessario ripensare se è davvero necessario eliminare il puntatore. – bta

3

E 'una variabile di stack (il modo in cui hai scritto), e quindi tenuti al campo di applicazione hai dichiarato in. Una volta che si colpisce la parentesi graffa di chiusura di quel particolare campo di applicazione, sarà ottenere ripulito senza di te dovendo fare qualcosa al riguardo.

Se si vuole essere assolutamente sicuri che nient'altro può usare pointer1 più a lungo, è possibile impostare pointer1=NULL una volta finito.

4

Quando si dichiara staticamente un puntatore con int* pointer1;, è possibile impostare libero. È possibile liberare solo la memoria allocata in modo dinamico allocata utilizzando new, malloc, ecc. L'unico modo per "liberarsi di" pointer1 è di lasciarlo fuori dall'ambito, ad esempio quando la funzione restituisce. Se hai finito di usare pointer1 e vuoi impedire che venga usato per alterare la matrice, usa pointer1 = NULL;.

1

Ignora semplicemente il puntatore e scompare quando hai terminato la funzione o il blocco. Ricorda che una volta che non hai più un puntatore a qualcosa, non sarà possibile accedervi. Certo, sarà ancora lì a usare la memoria, ma non sarai in grado di arrivarci. Quindi, prima di considerare di lasciar andare il puntatore, assicurati di avere un altro puntatore da qualche parte o di liberartene.

4

Normalmente per rendere un puntatore "sicuro" è sufficiente impostarlo su NULL, il che non punta a nulla. O puoi lasciarlo andare fuori dal campo di applicazione.

Ad esempio, se si dispone di due puntatori.

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

// somewhere  
b = NULL; 

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

Oppure puoi lasciarlo fuori portata.

int *a = new int; 

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

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

Does 'b = NULL; cancella b' fai qualcosa? È definito? Avevo l'impressione che fosse una specie di bug o comportamento indefinito. –

+0

@Nathan: 'foo = NULL; elimina foo; 'è perfettamente legale e innocuo. Significa che non è necessario cercare sempre non NULL-ness prima di eliminarlo. –

Problemi correlati