È sicuro assumere che lo storage vettoriale STL sia sempre contiguo?

Se si ha un vettore STL che è stato ridimensionato, è sicuro prendere l’indirizzo dell’elemento 0 e assumere che il resto del vettore seguirà in memoria?

per esempio

vector vc(100); // do some stuff with vc vc.resize(200); char* p = &vc[0]; // do stuff with *p 

Sì, questa è un’ipotesi valida (*).

Dallo standard C ++ 03 (23.2.4.1):

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’id quadro & v [n] == & v [0] + n per tutto 0 <= n

(*) … ma attenzione perché l’array venga riallocato (invalidando qualsiasi puntatore ed iteratore) dopo aver aggiunto gli elementi ad esso.

Lo standard C ++ 03 ha aggiunto la dicitura per chiarire che gli elementi vettoriali devono essere contigui.

C ++ 03 23.2.4 Il paragrafo 1 contiene la seguente lingua che non si trova nel documento standard C ++ 98:

Gli elementi di un vector sono memorizzati in modo contiguo, il che significa che se v è un vector dove T è un tipo diverso dal bool , quindi obbedisce all’identity framework &v[n] == &v[0] + n per tutti 0 <= n < v.size() .

Herb Sutter parla di questo cambiamento in uno dei suoi post sul blog, Cringe not: I vettori sono garantiti come contigui :

... la contiguità è in realtà parte dell'astrazione vettoriale. È così importante, infatti, che quando è stato scoperto che lo standard C ++ 98 non garantiva completamente la contiguità, lo standard C ++ 03 è stato modificato per aggiungere esplicitamente la garanzia.

Lo spazio di archiviazione è sempre contiguo, ma può spostarsi man mano che la capacità del vettore viene modificata.

Se si aveva un puntatore, un riferimento o un iteratore sull’elemento zero (o qualsiasi elemento) prima di un’operazione di modifica della capacità, viene invalidato e deve essere riassegnato.

Sì, è contiguo

std::vector garantisce che gli elementi siano memorizzati in un array contiguo, ed è quindi la sostituzione preferita degli array e può anche essere utilizzato per interfacciarsi con codice di basso livello dipendente dalla piattaforma (come le chiamate API Win32). Per ottenere un puntatore all’array utilizzare:

 &myVector.front(); 

sì.

dovrebbe sempre essere contiguo