2012-01-15 13 views
8

ero alla ricerca su questo argomento e ho trovato molti modi per convertire una matrice [] a uno std :: vector, come l'utilizzo di:Copia di una matrice in uno std :: vector

assign(a, a + n) 

o, in diretta il costruttore:

std::vector<unsigned char> v (a, a + n); 

Coloro risolvere il mio problema, ma mi chiedo se è possibile (e corretto) di fare:

myvet.resize(10); 
memcpy(&myvet[0], buffer, 10); 

mi chiedo questo perché ho il seguente codice:

IDiskAccess::ERetRead nsDisks::DiskAccess::Read(std::vector<uint8_t>& bufferRead, int32_t totalToRead) 
{ 
    uint8_t* data = new uint8_t[totalToRead]; 
    DWORD totalRead; 
    ReadFile(mhFile, data, totalToRead, &totalRead, NULL); 
    bufferRead.resize(totalRead); 
    bufferRead.assign(data, data + totalRead); 
    delete[] data; 

    return IDiskAccess::READ_OK; 
} 

E vorrei fare:

IDiskAccess::ERetRead nsDisks::DiskAccess::Read(std::vector<uint8_t>& bufferRead, int32_t totalToRead) 
{ 
    bufferRead.resize(totalToRead); 
    DWORD totalRead; 
    ReadFile(mhFile, &bufferRead[0], totalToRead, &totalRead, NULL); 
    bufferRead.resize(totalRead); 

    return IDiskAccess::READ_OK; 
} 

(Ho rimosso il trattamento degli errori della funzione ReadFile per semplificare il post).

Sta funzionando, ma temo che non sia sicuro. Credo che sia ok, dato che la memoria utilizzata dal vettore è continua, ma non ho mai visto qualcuno usare i vettori in questo modo.

È corretto utilizzare vettori come questo? C'è qualche altra opzione migliore?

risposta

8

Sì, è sicuro con std::vector Lo standard C++ garantisce che gli elementi vengano archiviati in posizioni di memoria contigue.

C++ 11 standard:

23.3.6.1 Classe panoramica templatevector [vector.overview]

Un vettore è un contenitore di sequenza che supporta iteratori ad accesso casuale. Inoltre, i suoi supporti (ammortizzati) inseriscono e cancellano il tempo costante alla fine; inserire e cancellare nel mezzo prendere tempo lineare. La gestione dell'archiviazione viene gestita automaticamente, sebbene possano essere forniti suggerimenti per migliorare l'e ffi cienza. Gli elementi di un vettore sono memorizzati in modo contiguo, il che significa che è IFV avector whereT è un certo tipo diverso bool, quindi obbedisce l'identità & v [n] == & v [0] + n per all0 < = n < v .dimensione().

1

Effettua il ridimensionamento prima e dovrebbe funzionare correttamente.

vector<int> v; 
v.resize(100); 
memcpy(&v[0], someArrayOfSize100, 100 * sizeof(int)); 
+3

Lui * fa * ridimensiona prima (vedere la prima riga della sua funzione). – celtschk

+1

Non stavo insinuando che non ci riuscisse. Stavo solo sottolineando la sua importanza. – TheBuzzSaw

+1

Potresti non aver * inteso * per implicarlo, ma l'hai fatto. – celtschk

2

La memoria in vector è garantito da assegnare in modo contiguo, e unsigned char è POD, quindi è del tutto sicuro per memcpy in esso (supponendo che non si copia più di quello che avete assegnato, naturalmente).

1

Sì, la soluzione che utilizza memcpy è corretta; il buffer detenuto da un vector è contiguo. Ma non è abbastanza sicuro dal tipo, quindi preferisci assign o std::copy.

5

Sì, è giusto farlo. Potresti voler fare myvet.data() invece di &myvet[0] se ti sembra migliore, ma entrambi hanno lo stesso effetto.Inoltre, se le circostanze lo consentono, puoi usare std::copy invece e avere più sicurezza di tipo e tutte quelle altre chicche della libreria standard C++.

La memoria utilizzata da vector è contigua, il che la rende adatta all'uso come buffer o con altre funzioni.

Assicurarsi di non modificare il vector (ad esempio la chiamata push_back su di esso, ecc) mentre si utilizza il puntatore si ottiene da data o &v[0] perché il vector potrebbe ridimensionare il suo buffer su una di quelle operazioni e invalidare il puntatore.

3

Questo approccio è corretto, dipende solo dal vettore con memoria contigua che è richiesto dallo standard. Credo che in C++ 11 ci sia una nuova funzione membro data() in vettori che restituisce un puntatore al buffer. Si noti inoltre che nel caso di `memcpy è necessario passare la dimensione in byte e non la dimensione dell'array

Problemi correlati