Domanda

In altre parole, in che modo l'implementazione tiene traccia del conteggio?

Esiste un oggetto simile a una mappa mantenuto che sia accessibile a tutti shared_ptr istanze la cui chiave è l'indirizzo del puntatore e il valore è il numero di riferimenti?Se devo implementare a shared_ptr, questa è la prima idea che mi viene in mente.

Esiste la possibilità che si verifichi una perdita di memoria in caso di questi puntatori intelligenti con conteggio dei riferimenti?Se sì, come posso evitarli?

È stato utile?

Soluzione

Ho visto due diversi approcci non-intrusive a questo:

  1. Il puntatore intelligente assegna un piccolo blocco di memoria per contenere la contatore di riferimento. Ogni copia del puntatore intelligente riceve poi una puntatore all'oggetto effettivo e puntatore al conteggio dei riferimenti.
  2. Oltre a un puntatore oggetto, ogni puntatore intelligente contiene precedente e successivo puntatore, così formando una lista doppiamente concatenata di puntatori intelligenti per un particolare oggetto. Il conteggio di riferimento è implicita nella lista. Quando una smart puntatore viene copiato, si aggiunge alla la lista. Su distruzione, ciascun puntatore intelligente per sé sottrae la lista. Se è l'ultimo in la lista è poi libera la oggetto referenziato come bene.

Se si va qui e scorrere fino alla fine, v'è un eccellente diagramma che spiega questi metodi molto più chiaramente.

Altri suggerimenti

Creare una perdita di memoria con puntatori intelligenti con conteggio dei riferimenti è molto semplice.Basta creare qualsiasi struttura di oggetti simile a un grafico che abbia un ciclo nel grafico.Gli oggetti nel ciclo impediranno il rilascio reciproco.Questo non può essere risolto automaticamente: ad esempio, quando crei un elenco a doppio collegamento devi fare attenzione a non rimuovere mai più di un oggetto alla volta.

Ogni oggetto puntatore intelligente contiene un conteggio di riferimento condiviso -. Uno per ogni indicatore grezzo

Si potrebbe dare un'occhiata al questo articolo . Questa implementazione memorizza questi in un oggetto separato che viene copiato intorno. Si potrebbe anche dare un'occhiata a o date un'occhiata alla Wikipedia articolo su puntatori intelligenti.

No. shared_ptr solo mantenere un puntatore aggiuntivo per il conteggio di riferimento.

Quando si effettua la copia di shared_ptr oggetto copiarlo puntatore con conteggio di riferimenti, aumentarlo, e copiare il puntatore su oggetto contenuto.

Per quanto mi ricordo, c'era il problema di puntatore conteggio dei riferimenti trattata in un capitolo del Effective C ++.

In linea di principio, si ha la "luce" di classe puntatore, che contiene un puntatore a una classe che tiene il riferimento che conosce per aumentare / di riferimento decremento e distruggere l'oggetto puntatore. Che i punti di classe conteggio riferimento all'oggetto da riferimento.

Molte risposte affrontano il modo in cui il conteggio dei riferimenti viene memorizzata (viene memorizzato in una memoria condivisa per tutti shared_ptr che detengono lo stesso puntatore nativo), ma la maggior parte eludono il problema di perdite.

Il modo più semplice di perdite di memoria con riferimento contati puntatori è creare cicli. A titolo di esempio, una lista doppiamente concatenata in cui tutti i puntatori sono shared_ptr con almeno due elementi è garantita non da cancellare. Anche se i puntatori esterni vengono liberati, i puntatori interni saranno ancora contare, e il conteggio dei riferimenti non raggiungerà 0. Questo è, almeno, con l'implementazione più ingenuo.

La soluzione più semplice al problema del ciclo è la miscelazione shared_ptr (riferimento contati puntatori) con i puntatori deboli che non condividono la proprietà dell'oggetto.

puntatori condivisi condivideranno sia la risorsa (puntatore) e le informazioni REFERENCE_COUNT supplementari. Quando si utilizzano i puntatori deboli, il conteggio dei riferimenti è raddoppiato: c'è un conteggio di riferimento puntatore condiviso e un conteggio di riferimento puntatore debole. La risorsa viene rilasciata ogni volta che il conteggio puntatore condiviso raggiunge lo 0, ma le informazioni REFERENCE_COUNT è rimasto vivo fino all'ultimo puntatore deboli viene rilasciato.

Nella lista doppiamente collegata, si svolge il riferimento esterno in uno shared_ptr, mentre i collegamenti interni sono solo weak_ptr. Ogni volta che ci sono riferimenti esterni (shared_ptr) gli elementi della lista vengono rilasciati, eliminando i riferimenti deboli. Alla fine tutti i riferimenti deboli sono stati cancellati e l'ultimo puntatore debole per ogni risorsa libera le informazioni REFERENCE_COUNT.

E 'meno confusione rispetto al testo di cui sopra sembra ... proverò più tardi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top