¿Es seguro asumir que el almacenamiento de vectores STL es siempre contiguo?

StackOverflow https://stackoverflow.com/questions/247738

  •  05-07-2019
  •  | 
  •  

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
¿Fue útil?

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 si v es un   vector<T, Allocator> donde T es   algún tipo que no sea bool, entonces   obedece la identidad &v[n] == &v[0] + n para todos los 0 <= 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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top