2011-11-22 7 views
6

questo è abbastanza inverosimile, ma è il seguente codice "sicuro" (cioè sia garantito contro eventuali errore di segmentazione):Sta entrando nel puntatore raw dopo std :: vector :: reserve safe?

std::vector<int> vec(1); // Ensures that &vec[0] is valid 
vec.reserve(100); 
memset(&vec[0], 0x123, sizeof(int)*100); // Safe? 

mi rendo conto che questo è brutto - mi interessa solo sapere se è tecnicamente sicura , non carino". Immagino che il suo unico utilizzo potrebbe essere quello di ignorare i valori memorizzati oltre un determinato indice.

Nota! How can I get the address of the buffer allocated by vector::reserve()? copre lo stesso argomento, ma sono più interessato se si tratta di sicuro e se ci sono problemi a farlo.

MODIFICA: il codice originale era errato, sostituito originale memcpy con memset.

+1

Ok, questo è così brutto che fa male. Perché lo stai facendo? Non puoi semplicemente usare un array, se proprio devi? In questo esempio 100 è fisso, quindi è possibile utilizzare una matrice nello stack senza eliminare anche [] ing ... – Francesco

+2

"Errore di segmentazione" è un evento specifico della piattaforma. Il linguaggio C++ non descrive quello che è. La lingua dice solo se qualcosa è definito, e se è così, per fare cosa. –

+1

Ho svalutato la domanda, non perché la considero una domanda sbagliata, ma perché non hai impiegato abbastanza tempo per assicurarti che quello che stavi chiedendo fosse quello che volevi chiedere (il codice originale e il codice nella versione attuale sono piuttosto diverso).-2 punti Rep non sono molti, ma in futuro dovresti ricordarti di essere un po 'più cauti, come quando chiedi alle altre persone il tempo di rispondere cercando di aiutare, ed è il momento che si perde se riformuli la domanda più tardi sopra. –

risposta

16

No, non è sicuro.

Dopo un reserve(), il vettore è garantito per non riallocare la memoria finché non viene raggiunto capacity().

Tuttavia, lo standard non dice cosa può fare l'implementazione vettoriale con lo spazio di archiviazione tra size() e capacity(). Forse può essere usato per alcuni dati interni - chi lo sa? Forse lo spazio degli indirizzi è solo riservato e non mappato alla RAM effettiva?

L'accesso agli elementi al di fuori di [0..size] è un comportamento non definito. Ci potrebbe essere un po 'di controllo hardware per quello.

+0

upped per indicare _why_ questa è una cattiva idea: la memoria riservata è UB e non è disponibile 'ufficialmente' tramite il vettore finché non è stato 'ridimensionato'd o' push'/'emplace'd to. –

2

Vector-riallocazione invalida esistenti puntatori, riferimenti ecc Riserva potrebbe innescare una riallocazione (23.3.6.2, [vector.capacity]), ma si sta prendendo l'indirizzo del primo elemento dopo l'eventuale riallocazione (che in questo caso probabilmente non accadrà affatto, ma questo è oltre il punto). Quindi non vedo alcun problema con il codice.

+0

Ho aggiornato la mia domanda per usare memset piuttosto che 'memcpy (il mio esempio non era corretto). – larsmoa

2

Innanzitutto, lo memset troncherà lo 0x123 in un singolo byte e lo scriverà, senza scrivere un modello a quattro byte.

Quindi, non fare così, basta usare il contenitore: std::vector<int> vec(100, whatever_value_you_want);

Tuttavia, per rispondere alla domanda se può sembrare a lavorare in modo specifico per i tipi di POD se il compilatore non usa lo spazio allocato per qualsiasi cosa. Certamente, se qualcuno chiama resize, insert, push_back ecc., Farà saltare via tutto ciò che hai già scritto nella memoria e anche la dimensione del vettore sarà sbagliata. Non c'è alcun motivo per scrivere questo codice.

Problemi correlati