Domanda

Sto cercando un modo per mettere grandi array di dati (memorizzati all'interno di una classe in possesso di funzionalità di base come i controlli sui dati, dimensioni ecc) in qualsiasi contenitore STL, come un vettore o di una coda (FIFO coda è migliore da quando sono avere un produttore e un consumatore).

Il problema è che ho per implementare il costruttore di copia e .. beh .. non voglio fare una copia profonda (perché ci vuole troppo tempo, quindi mi attengo a una copia), ma poi di nuovo ho il problema di non sapere quando per cancellare la matrice di dati nel distruttore (dato che io chiamo il distruttore due volte e hanno solo i dati una volta, in più, la prima chiamata al distruttore probabilmente proviene da inserire / spostare l'elemento nel contenitore , quindi ho ancora bisogno la matrice-dati a quel punto).

Ho pensato di usare puntatori intelligenti come std :: shared_ptr per l'array di dati, ma da quello che ho letto non si chiama delete [], ma piuttosto di eliminazione - che è un peccato dal momento che ho una matrice ordinaria [].

In questo momento ho una soluzione che a mano chiama una funzione "DeleteArray" sulla classe prima di rimuoverla dal contenitore. E le grandi opere, ma .. non è bello.

Tutte le idee?

È stato utile?

Soluzione

Boost ha una classe shared_array che è come shared_ptr ma utilizzerà delete[], oppure è possibile aggiungere un deleter personalizzato per shared_ptr che renderà chiamare delete[].

Altri suggerimenti

Non utilizzare una matrice, utilizzare un std::vector invece. Poi puntare a che con un puntatore intelligente.

Ancora meglio la soluzione sarebbe quella di mettere shared_ptrs ai vostri oggetti di grandi dimensioni nei contenitori ed evitare copie costose tutti insieme.

Modifica 0:

Un'altra opzione, naturalmente, è quello di rendere gli oggetti stessi leggero e copiabile con shared_array. come suggerisce Geremia.

C'è un shared_ptr equivalente per gli array, almeno nelle librerie Boost. Si chiama shared_array, e si comporta esattamente come ci si aspetterebbe. Scopri le specifiche a http: // www. boost.org/doc/libs/1_45_0/libs/smart_ptr/shared_array.htm?sess=8940ad57baa307d68cb2e7fd2939d2db .

È possibile implementare semplice conteggio dei riferimenti nel vostro costruttore di copia. È possibile diminuire il riferimento ad ogni eliminazione.

Molte grazie per tutte le vostre risposte penetranti!

Questo mi ricorda il motivo per cui l'ultima volta che ho avuto questo problema che ho handcoded una coda senza copiare me stesso. Non posso dire che mi ha portato molto più tempo di capire come fare la bella, versione pulita. :)

Quindi .. quello che ho fatto è:

Soluzione a) Come descritto nel post originale, ho creato una funzione che doveva essere chiamato in modo esplicito prima di rimuovere una classe dal vettore. Non bello, ma ha funzionato grande e non ho avuto a pasticciare con qualsiasi altra cosa, basta ricordarsi di chiamarlo.

Soluzione b) Ho messo la matrice in un'altra classe e usato una smart pointer (shared_ptr) a tale classe. Ha lavorato veramente bello. Ho dovuto usare shared_ptr s come elementi del vettore anche. (Non ho pensato di questo in un primo momento).

Soluzione c) Utilizzando shared_ptr per tenere un array. Abbastanza cattiva idea, come si scopre, perché chiama elimina anziché eliminare [] è necessario fornire il proprio deleter personalizzato e in qualche modo qualche altro (sintassi) i problemi sono emersi in modo che mi ha portato qualcosa come 2h + per farlo soluzione.

Sembra qualcosa di simile nel file di intestazione:

 template< typename T >
  struct
array_deleter
  {
      void
    operator ()( T const * p)
      { delete[] p; }
  };

class MemoryStressChunk
{
private:
    int chunkSizeInValues;
    std::shared_ptr< __int64 > data;
};

e nel file di codice:

data.reset(
    new __int64[chunkSizeInValues], 
    array_deleter< __int64 >() );

e di utilizzarlo devo farlo di nuovo:

__int64 *d = data.get();

La prossima volta potrebbe prendere in seria considerazione utilizzando le versioni boost. Non ho avuto spinta sulla mia macchina in modo che è il motivo per cui non era un'opzione per me.

Io lo prendo Soluzione d) sarebbe quella di utilizzare un vettore di classi contenenti uno shared_ptr s ad un vettore (anziché un array). Dopo tutto il divertimento che ho avuto con c) non ho fatto che sulla parte superiore. :)

Se qualcuno vuole avere uno sguardo al codice, si può ottenere qui http://andreas-reiff.de/wp-content/uploads/2011/01/Tool-MemTester.zip . Attenzione non è probabilmente un memleak nella versione a) (uso shared_ptr per la classe, come nella versione b)).

Thx per tutto il tuo aiuto di nuovo!

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