2009-02-05 18 views

risposta

8

Se si dispone di uno scenario in cui molti puntatori all'interno della propria app fanno riferimento agli stessi oggetti a durata limitata, una soluzione popolare è utilizzare boost smart pointers. Edit: in C++ 11, entrambi questi tipi sono disponibili nella libreria standard

Si consiglia di utilizzare shared_ptr per puntatore (s) che sono responsabili per tutta la durata del vostro oggetto e weak_ptr per gli altri puntatori , che potrebbe diventare non valido. Vedrai che weak_ptr ha il controllo di validità che stai richiedendo integrato.

+0

Non ho usato shared_prt ma per quanto ho capito è un puntatore che controlla la vita di un oggetto Ho una situazione opposta Ho un oggetto che può cancellare se stesso dopo aver ricevuto un messaggio Ho bisogno di quelli che lo indicano per avere un modo per sapere che possiedono s puntatore non valido. – jackhab

+1

Questo è esattamente il tipo di caso in cui è stato creato weak_ptr. Weak_ptr lascerà morire l'oggetto e segnalerà l'invalidità se in seguito tenterai di accedere all'oggetto tramite weak_ptr. Una soluzione decisamente migliore rispetto a SIGSEGV! – timday

+0

Questo è quello che pensavo fosse la tua situazione. Il messaggio "delete me" dovrebbe resettare il solo_un_padrone condiviso. Dopodiché, tutti i weak_ptr creati da that shared_ptr sapranno che non sono validi. Dai un'occhiata al link weak_ptr per gli esempi. –

4

Inizializza il puntatore su NULL. Se dopo qualche elaborazione è ancora NULL non è valido, altrimenti è valido.

+0

Se elimino un oggetto che sia il puntatore non è NULL ma punta alla memoria non valida. Come posso convalidare tale puntatore? – jackhab

+1

Perché diavolo vorresti? L'hai cancellato. Se stai usando i puntatori ovunque e non sei sicuro che siano eliminati o no, stai facendo qualcosa di MOLTO sbagliato. – Bombe

+0

Secondo. I puntatori non validi sono indicatori non validi. In seguito, la variabile puntatore non è più accessibile o lo imposti a 0. Oppure, dato che questo è C++, scopri RAII. – gimpf

4

È possibile abilitare un gestore di segnale per SIGSEGV per questa occorrenza. Vedi la pagina man "segnale" per i dettagli. L'altra alternativa è usare riferimenti che sono garantiti come validi. Dipende dalla tua applicazione, naturalmente.

+0

La pagina man dice che lo stato del processo non è definito se ignora SIGSEGV. Posso riprendere l'applicazione C++ dopo aver catturato SIGSEGV? – jackhab

+0

Buona domanda, probabilmente non sicura. Penso che sia generalmente meglio usare riferimenti anziché puntatori se sei preoccupato per la validità. Come hanno sottolineato gli altri utenti, puoi registrare dove si verifica l'errore e correggerlo. –

+0

Anche i riferimenti non sono garantiti come validi. Se la durata dell'oggetto referenziato termina prima dell'uso del riferimento, anche i risultati sono indefiniti (in pratica identici a un puntatore non valido). I riferimenti non possono essere inizializzati su null e non resettati. Questo è tutto. – gimpf

8

Un errore di segmentazione non è un'eccezione (come NullPointerException di Java); è un segnale inviato dal sistema operativo al processo. Dai un'occhiata a the manpage for sigaction per i puntatori su come installare un gestore per l'errore di segmentazione (SIGSEGV).

1

Come si verifica il puntatore per la validità? Confronta con NULL?

La cosa migliore da fare è eseguire il programma in Valgrind. Un bug potrebbe essere in un posto abbastanza diverso.

Aggiornamento: Sulla piattaforma Win32 c'è qualcosa come __try __except che consente di rilevare alcune eccezioni. Per quanto ne so, non esiste un equivalente Linux per quella funzionalità di Win32.

+0

Su Windows è possibile rilevare un'eccezione quando si accede a un puntatore all'oggetto deallocato e si può affrontare la situazione.In Linux si ottiene SIGSEGV. La mia domanda è un modo per convalidare un puntatore che una volta puntava a un oggetto e quindi non è NULL ma ancora invalidato dall'operatore delete. – jackhab

+0

Non sono un esperto di Win32 ma una volta ho usato __try __eccetto per tali cose. –

+0

Queste sono solo le cose di Windows, esponendo l'eccezione Strutturata della piattaforma gestione "(SEH) in C++. L'equivalente linux è segnali ... ma penso che il suggerimento di Shmoopty di shared_ptr/weak_ptr sia più lungo la linea giusta. – timday

0

Se si collega un gestore al SIGSEGV, non c'è molto che si possa fare oltre a registrare il fatto che l'errore si è verificato e fallire con garbo. Il tuo programma si trova in uno stato indefinito quando si verifica questa violazione e quindi potrebbe non essere sicuro continuare il normale funzionamento.

Oltre il controllo per NULL, non credo ci sia un modo per verificare se un puntatore è "valido" nel senso che stai descrivendo. Durante il normale funzionamento, errori come questo non dovrebbero accadere in quanto rappresentano un bug, quindi dovresti volere che il tuo programma fallisca, anche se con grazia.

0

I puntatori sono memorizzati in oggetti. Sono inizializzati nel costruttore, potenzialmente su 0 (NULL). Vengono eliminati nel distruttore, possibilmente in assegnazione e raramente in altre funzioni. Quando vengono eliminati in membri diversi dal distruttore, viene immediatamente assegnato un nuovo valore o 0.

2

Non esiste un modo naturale e universale con puntatori C++ non elaborati. C++ presuppone che traccerai quell'informazione.

Nella maggior parte dei casi, è possibile gestirlo ricordando di impostare i puntatori su NULL quando non sono validi. I nuovi puntatori che inizialmente non puntano dovrebbero essere impostati su NULL e gli oggetti appena eliminati dovrebbero avere i loro puntatori impostati su NULL.

Problemi correlati