Sono std :: elementi vettoriali garantiti contigui?

La mia domanda è semplice: sono std: elementi vettoriali garantiti contigui? Nella parola ordine, posso usare il puntatore al primo elemento di un vettore std :: come un C-array?

Se la mia memoria mi serve bene, lo standard C ++ non ha reso tale garanzia. Tuttavia, i requisiti di std :: vector erano tali che era praticamente imansible soddisfarli se gli elementi non erano contigui.

Qualcuno può chiarirlo?

Esempio:

std::vector values; // ... fill up values if( !values.empty() ) { int *array = &values[0]; for( int i = 0; i < values.size(); ++i ) { int v = array[i]; // do something with 'v' } } 

    Ciò è mancato dallo standard C ++ 98, ma successivamente aggiunto come parte di un TR. Il prossimo standard C ++ 0x ovviamente lo contatterà come requisito.

    Da n2798 (bozza di C ++ 0x):

    23.2.6 Vettore modello di class [vettore]

    1 Un vettore è un contenitore di sequenza che supporta iteratori di accesso casuale. Inoltre, supporta operazioni di inserimento e cancellazione costanti (ammortizzate) 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’efficienza. Gli elementi di un vettore sono memorizzati in modo contiguo, nel senso che se v è un vettore in cui T è un tipo diverso dal bool, allora obbedisce all’identity framework & v [n] == & v [0] + n per tutto 0 <= n

    Come hanno sottolineato altre risposte, il contenuto di un vettore è garantito come continuo (ad eccezione della stranezza di bool).

    Il commento che volevo aggiungere è che se si esegue un inserimento o una cancellazione sul vettore, che potrebbe causare la riallocazione della memoria da parte del vettore, allora tutti i puntatori e gli iteratori salvati verranno invalidati.

    Lo standard infatti garantisce che un vector sia continuo nella memoria e che &a[0] possa essere passato ad una funzione C che si aspetta un array.

    L’eccezione a questa regola è il vector che usa solo un bit per bool quindi sebbene abbia memoria continua non può essere usato come bool* (questo è ampiamente considerato come una falsa ottimizzazione e un errore).

    A proposito, perché non usi gli iteratori? Ecco a cosa servono.

    Come altri hanno già detto, il vector usa internamente una serie contigua di oggetti. I puntatori in quell’array dovrebbero essere considerati non validi ogni volta che una funzione membro non const viene chiamata IIRC.

    Tuttavia, c’è un’eccezione !!

    vector ha un’implementazione specializzata progettata per risparmiare spazio, in modo che ogni bool utilizza solo un bit. L’array sottostante non è un array contiguo di bool e aritmetica dell’array sul vector non funziona come farebbe il vector .

    (Suppongo sia anche ansible che questo possa essere vero per qualsiasi specializzazione del vettore, dal momento che possiamo sempre implementarne uno nuovo. Tuttavia, std::vector è l’unica, errata, specializzazione standard sulla quale il semplice aritmetico del puntatore ha vinto ” t lavoro.)

    Ho trovato questo thread perché ho un caso d’uso in cui i vettori che utilizzano memoria contigua sono un vantaggio.

    Sto imparando come usare gli oggetti buffer vertice in OpenGL. Ho creato una class wrapper per contenere la logica del buffer, quindi tutto ciò che devo fare è passare una serie di float e alcuni valori di configurazione per creare il buffer. Voglio essere in grado di generare un buffer da una funzione basata sull’input dell’utente, quindi la lunghezza non è nota al momento della compilazione. Fare qualcosa del genere sarebbe la soluzione più semplice:

     void generate(std::vector v) { float f = generate_next_float(); v.push_back(f); } 

    Ora posso passare i float del vettore come una matrice alle funzioni relative al buffer di OpenGL. Ciò rimuove anche la necessità di sizeof per determinare la lunghezza dell’array.

    Questo è molto meglio dell’assegnazione di un enorme array per immagazzinare i float e sperare di averlo reso abbastanza grande, o di creare il mio array dinamico con storage contiguo.

    Sì, gli elementi di un vettore std :: sono garantiti contigui.

    cplusplus.com:

    I contenitori vettoriali sono implementati come array dinamici; Proprio come gli array regolari, i contenitori vettoriali hanno i loro elementi memorizzati in posizioni di memoria contigue, il che significa che i loro elementi sono accessibili non solo usando gli iteratori ma anche usando gli offset su puntatori regolari agli elementi.