Come copi il contenuto di un array in un file std :: vector in C ++ senza eseguire il loop?

Ho una matrice di valori che viene trasmessa alla mia funzione da una parte diversa del programma che ho bisogno di memorizzare per un’elaborazione successiva. Dato che non so quante volte verrà chiamata la mia funzione prima che sia il momento di elaborare i dati, ho bisogno di una struttura di archiviazione dynamic, quindi ho scelto un std::vector . Non voglio dover fare il ciclo standard per push_back tutti i valori individualmente, sarebbe bello se potessi semplicemente copiare tutto usando qualcosa di simile a memcpy .

Se riesci a build il vettore dopo aver ottenuto la matrice e le dimensioni dell’array, puoi semplicemente dire:

 std::vector vec(a, a + n); 

… assumendo a è il tuo array e n è il numero di elementi che contiene. Altrimenti, std::copy() w / resize() farà il trucco.

memcpy() lontano da memcpy() meno che non si possa essere sicuri che i valori siano semplici vecchi dati (POD).

Inoltre, vale la pena notare che nessuno di questi evita davvero il ciclo for – è solo una questione se devi vederlo nel tuo codice oppure no. O (n) le prestazioni di runtime sono inevitabili per la copia dei valori.

Infine, si noti che gli array in stile C sono contenitori perfettamente validi per la maggior parte degli algoritmi STL: il puntatore raw è equivalente a begin() e ( ptr + n ) è equivalente a end() .

Ci sono state molte risposte qui e quasi tutte faranno il lavoro.

Tuttavia c’è qualche consiglio fuorviante!

Ecco le opzioni:

 vector dataVec; int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; unsigned dataArraySize = sizeof(dataArray) / sizeof(int); // Method 1: Copy the array to the vector using back_inserter. { copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec)); } // Method 2: Same as 1 but pre-extend the vector by the size of the array using reserve { dataVec.reserve(dataVec.size() + dataArraySize); copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec)); } // Method 3: Memcpy { dataVec.resize(dataVec.size() + dataArraySize); memcpy(&dataVec[dataVec.size() - dataArraySize], &dataArray[0], dataArraySize * sizeof(int)); } // Method 4: vector::insert { dataVec.insert(dataVec.end(), &dataArray[0], &dataArray[dataArraySize]); } // Method 5: vector + vector { vector dataVec2(&dataArray[0], &dataArray[dataArraySize]); dataVec.insert(dataVec.end(), dataVec2.begin(), dataVec2.end()); } 

Per farla breve, il Metodo 4, usando vector :: insert, è il migliore per lo scenario di bsruth.

Ecco alcuni dettagli cruenti:

Il metodo 1 è probabilmente il più semplice da capire. Basta copiare ogni elemento dalla matrice e spingerlo nella parte posteriore del vettore. Ahimè, è lento. Perché c’è un ciclo (implicito con la funzione di copia), ogni elemento deve essere trattato singolarmente; non è ansible apportare miglioramenti delle prestazioni in base al fatto che sappiamo che l’array e i vettori sono blocchi contigui.

Il metodo 2 è un miglioramento delle prestazioni suggerito al Metodo 1; è sufficiente prenotare in anticipo la dimensione dell’array prima di aggiungerlo. Per i grandi array questo potrebbe aiutare. Tuttavia il miglior consiglio qui è di non usare mai la riserva a meno che la profilazione non suggerisca che potresti essere in grado di ottenere un miglioramento (o devi assicurarti che i tuoi iteratori non vengano invalidati). Bjarne è d’accordo . Per inciso, ho scoperto che questo metodo ha eseguito il più lento il più delle volte anche se ho difficoltà a spiegare in modo esaustivo perché era regolarmente molto più lento del metodo 1 …

Il metodo 3 è la soluzione vecchia scuola – lanciare qualche C al problema! Funziona bene e velocemente per i tipi di POD. In questo caso è necessario richiamare il ridimensionamento poiché memcpy lavora fuori dai limiti del vettore e non c’è modo di dire a un vettore che la sua dimensione è cambiata. Oltre ad essere una brutta soluzione (copiatura di byte!) Ricorda che questo può essere usato solo per i tipi di POD . Non userei mai questa soluzione.

Il metodo 4 è il modo migliore per andare. Il significato è chiaro, è (di solito) il più veloce e funziona per qualsiasi object. Non c’è nessun svantaggio nell’usare questo metodo per questa applicazione.

Il metodo 5 è un tweak sul Metodo 4 – copia l’array in un vettore e poi aggiungilo. Buona opzione – generalmente veloce e chiara.

Infine, sei consapevole che puoi utilizzare i vettori al posto degli array, giusto? Anche quando una funzione si aspetta array di c-style puoi usare i vettori:

 vector v(50); // Ensure there's enough space strcpy(&v[0], "prefer vectors to c arrays"); 

Spero che aiuti qualcuno là fuori!

Se tutto ciò che stai facendo è sostituire i dati esistenti, puoi farlo

 std::vector data; // evil global :) void CopyData(int *newData, size_t count) { data.assign(newData, newData + count); } 

std :: copy è quello che stai cercando.

Poiché posso modificare solo la mia risposta, creerò una risposta composita dalle altre risposte alla mia domanda. Grazie a tutti voi che avete risposto.

Usando std :: copy , questo continua a scorrere in background, ma non devi digitare il codice.

 int foo(int* data, int size) { static std::vector my_data; //normally a class variable std::copy(data, data + size, std::back_inserter(my_data)); return 0; } 

Usando la normale memcpy . Questo è probabilmente il migliore per i tipi di dati di base (cioè int) ma non per gli array più complessi di strutture o classi.

 vector x(size); memcpy(&x[0], source, size*sizeof(int)); 

evita la memcpy, dico. Non c’è motivo di fare casino con le operazioni del puntatore a meno che non sia davvero necessario. Inoltre, funzionerà solo per i tipi di POD (come int) ma fallirebbe se si tratta di tipi che richiedono una costruzione.

 int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//source unsigned dataArraySize = sizeof(dataArray) / sizeof(int); std::vector myvector (dataArraySize );//target std::copy ( myints, myints+dataArraySize , myvector.begin() ); //myvector now has 1,2,3,...10 :-) 

Oltre ai metodi presentati sopra, è necessario assicurarsi di utilizzare std :: Vector.reserve (), std :: Vector.resize () o di build il vettore in base alle dimensioni, per assicurarsi che il vettore abbia abbastanza elementi in per tenere i tuoi dati. in caso contrario, si corrompe la memoria. Questo vale per std :: copy () o memcpy ().

Questa è la ragione per usare vector.push_back (), non puoi scrivere oltre la fine del vettore.

Un’altra risposta, dal momento che la persona ha detto “Non so quante volte verrà chiamata la mia funzione”, è ansible utilizzare il metodo di inserimento vettoriale in questo modo per aggiungere matrici di valori alla fine del vettore:

 vector x; void AddValues(int* values, size_t size) { x.insert(x.end(), values, values+size); } 

Mi piace in questo modo perché l’implementazione del vettore dovrebbe essere in grado di ottimizzare il modo migliore per inserire i valori in base al tipo di iteratore e al tipo stesso. In qualche modo stai rispondendo all’implementazione di stl.

Se hai bisogno di garantire la massima velocità e sai che il tuo tipo è di tipo POD, ti consiglio il metodo di ridimensionamento nella risposta di Thomas:

 vector x; void AddValues(int* values, size_t size) { size_t old_size(x.size()); x.resize(old_size + size, 0); memcpy(&x[old_size], values, size * sizeof(int)); } 

Supponendo che tu sappia quanto è grande l’object nel vettore:

 std::vector myArray; myArray.resize (item_count, 0); memcpy (&myArray.front(), source, item_count * sizeof(int)); 

http://www.cppreference.com/wiki/stl/vector/start