2016-05-04 17 views
6

Sto cercando di risolvere alcuni codice che utilizza vettori un sacco e ci sono alcuni loop che assomigliano a questo:Come cancellare un vettore mantenendo la sua capacità?

for (int t=0;t<T;t++){  
    std::vector<double> vect; 
    for (int i=0;i<MAX;i++){ 
     double value; 
     vect.push_back(value); 
    } 
    /*....*/ 
} 

so più o meno come migliorare questo riutilizzando lo stesso vettore per le iterazioni esterne, ma mentre lo facevo, ho scoperto che quando chiamavo std::vector::clear"the vector capacity is not guaranteed to change", mentre speravo davvero che la capacità fosse garantita non cambiava. Forse sto solo fraintendendo ciò che è scritto su cplusplus.com. Tuttavia, la mia domanda è:

Come posso cancellare un vettore senza modificare la sua capacità?

Devo chiamare reserve dopo clear per verificare che la capacità sia la stessa?

PS: Giusto per essere chiari, voglio riscrivere sopra il codice a

std::vector<double> vect; 
vect.reserve(MAX); 
for (int t=0;t<T;t++){  
    for (int i=0;i<MAX;i++){ 
     double value; 
     vect.push_back(value); 
    } 
    /*....*/ 
    vect.clear(); 
} 

es. Voglio comunque riempirlo tramite push_back e sono preoccupato per il clear() che modifica la capacità del vettore.

+1

C'è una discussione correlata qui. Il consenso sembra essere che il ridimensionamento di un vettore SMALLER non deve affliggere la capacità. http://stackoverflow.com/questions/1624803/does-resizing-a-vector-invalidate-iterators – Roddy

+1

Una risposta migliore era http://stackoverflow.com/a/18467916 – Cubbi

+0

@Cubbi dopo aver letto la discussione che segue quella risposta , Sono abbastanza convinto che 'clear' non è autorizzato a cambiare la capacità, quindi la mia domanda è un po 'obsoleta (e cplusplus sembra essere sbagliato in quel punto). La mia lezione è: mai fidarsi di nessuno tranne lo standard;) – user463035818

risposta

4

Sì, chiamare reserve() dopo clear(). Nel peggiore dei casi, si avrà una singola deallocazione/allocazione che avrà un impatto trascurabile in caso di un vettore di POD.

+0

Non importa che si tratti di POD. Non è in corso alcuna costruzione di oggetti quando si chiama 'clear()' – Roddy

3

È possibile memorizzare il valore restituito da capacity() e utilizzare il metodo reserve().

Non è garantita per darvi la stessa capacity:

aumentare la capacità del contenitore per un valore che è maggiore o uguale a new_cap. Se new_cap è maggiore della capacità corrente(), la nuova memoria viene allocata, altrimenti il ​​metodo non esegue nulla.

int main() 
{ 
    vector<int> vec { 1,2,3,4,5 }; 
    size_t cap = vec.capacity(); 
    vec.clear(); 
    vec.reserve(cap); 

    cout << "vec capacity: " << vec.capacity() << '\n'; 
} 
+0

dove hai preso la citazione? In particolare, mi interessa sapere se è davvero garantito di non fare nulla nel caso in cui la capacità richiesta sia inferiore alla capacità attuale. Non che sarebbe così importante, ma a volte i dettagli contano – user463035818

+0

ah grazie, in realtà ero un po 'confuso, perché nella mia citazione ho confuso cppreference con cplusplus ... – user463035818

-1

Calling clear sarà deallocare (non necessariamente, ma a seconda della realizzazione), quindi chiamando resize comporterà una ridistribuzione costosa. La risposta ovvia sarebbe quella di scorrere solo se il vettore e per impostare i risultati 0/NULL:

for(double& d : vect) 
{ 
    d = 0; 
    //d = NULL, depending on datatype 
} 

Questo sarà solo "clear" il vettore senza una ridistribuzione costoso. Di conseguenza, l'esecuzione di questa procedura dipende in larga misura dal numero di elementi: questa è solo la via d'uscita facile.

+0

Non voglio ridimensionare. Le condizioni al contorno sono: Il vettore dovrebbe essere cancellato in modo che successivamente possa essere riempito di nuovo con 'push_back' fino alla stessa capacità. Scusa se questo non era chiaro – user463035818

+0

Va bene allora. Sembra che abbia frainteso; scusa. – calcyss

-1

Un altro modo sarebbe quello di fare un fare un trucco swap ...

std::vector<double> vect = {0.1, 0.2, 0.3} 
{ 
    std::vector<double> swapVector; 
    swapVector.reserve(vect.capacity()); 
    vect.swap(swapVector); // swapVector now has the elements of vect 
          // vect has only reserved elements 
} // swapVector will be destroyed (including the elements that was in vect) 
std::cout << vect.capacity(); 
+0

"il vect verrà cancellato quando esce dal campo" ?? Non capisco – user463035818

+0

@ tobi303 swapVector viene creato nello stack ed è stato scambiato con gli elementi in vect. Appena la funzione scompare, lo swapVector verrà distrutto e gli elementi ... lascia che modifichi la mia risposta –

+0

Vedo un sacco di svantaggi e nessun vantaggio per questo approccio. Stai forzando una deallocazione e una riallocazione (sebbene nell'altro ordine), che è esattamente ciò che l'OP vuole evitare, – Roddy

6

cppreference detto esplicitamente che la capacità del vettore è invariato.

da cppreference (grassetto accenti sono io proprio):

void clear(); 

Rimuove tutti gli elementi dal contenitore. Invalida eventuali riferimenti, puntatori o iteratori che si riferiscono a elementi contenuti. Può invalidare qualsiasi iteratore passato-fine.
Lascia la capacità() del vettore invariato.

EDIT

Come sottolineato da Dmitry Kuznetsov nel commento, l'standard non menziona la capacità:

espressione: Tipoa.clear()

ritorno :void
Asserzione/nota pre/post-condizione: Distrugge tutti gli elementi in a. Invalida tutti i riferimenti, i puntatori e gli iteratori che si riferiscono agli elementi di a e possono invalidare l'iteratore passato-fine.

post: a.empty() restituisce true.

Complessità: Lineare.

+0

hm in tal caso sarebbe interessante quello che dice lo standard perché cplusplus afferma che questo non è garantito. – user463035818

+0

potrebbe essere che sia solo un errore di battitura su cplusplus e invece di "non garantire di cambiare" in realtà significava "garantito di non cambiare" – user463035818

+0

in caso di dubbio fare riferimento allo standard. Ad ogni modo non mi interesserebbe sapere cosa è scritto su cplusplus. – Slava

Problemi correlati