¿Es seguro asumir que el almacenamiento de vectores STL es siempre contiguo?
Pregunta
Si tiene un vector STL que ha sido redimensionado, ¿es seguro tomar la dirección del elemento 0 y asumir que el resto del vector seguirá en la memoria?
por ejemplo
vector<char> vc(100);
// do some stuff with vc
vc.resize(200);
char* p = &vc[0];
// do stuff with *p
Solución
Sí, esa es una suposición válida (*).
Del estándar C ++ 03 (23.2.4.1):
Los elementos de un vector se almacenan contiguamente, lo que significa que si v es un vector donde T es algo escriba otro que no sea bool, entonces obedece la identidad & amp; v [n] == & amp; v [0] + n para todos 0 < = n < v.size ().
(*) ... pero tenga cuidado con la matriz que se reasigna (invalidando los punteros e iteradores) después de agregarle elementos.
Otros consejos
El estándar C ++ 03 agregó texto para dejar en claro que los elementos vectoriales deben ser contiguos.
C ++ 03 23.2.4 El párrafo 1 contiene el siguiente lenguaje que es no en el documento estándar de C ++ 98:
Los elementos de un
vector
se almacenan contiguamente, lo que significa que siv
es unvector<T, Allocator>
dondeT
es algún tipo que no seabool
, entonces obedece la identidad&v[n] == &v[0] + n
para todos los0 <= n < v.size()
.
Herb Sutter habla sobre este cambio en una de sus entradas de blog, Cringe not: se garantiza que los vectores son contiguos :
... la contigüidad es, de hecho, parte de la abstracción vectorial Es & # 8217; es tan importante, de hecho, cuando se descubrió que el estándar C ++ 98 no & # 8217; t garantizamos completamente la contigüidad, el El estándar C ++ 03 se modificó a agregue explícitamente la garantía.
El almacenamiento siempre es contiguo, pero puede moverse a medida que cambia la capacidad del vector.
Si tenía un puntero, referencia o iterador en el elemento cero (o cualquier elemento) antes de una operación de cambio de capacidad, se invalida y debe reasignarse.
std::vector
garantiza que los elementos se almacenan en una matriz contigua y, por lo tanto, es el reemplazo preferido de las matrices y también se puede utilizar para interactuar con el código de bajo nivel dependiente de la plataforma (como las llamadas a la API Win32). Para obtener un puntero a la matriz, use:
&myVector.front();
sí.
siempre debe ser contiguo