vectors new example espaƱol c++ arrays vector

new - std:: vector versus std:: array en C++



vector c++ example (6)

¿Cuál es la diferencia entre un std::vector y un std::array en C ++? ¿Cuándo debería uno ser preferido sobre otro? ¿Cuáles son los pros y los contras de cada uno? Todo lo que hace mi libro de texto es enumerar cómo son iguales.


Para enfatizar un punto hecho por @MatteoItalia, la diferencia de eficiencia es donde se almacenan los datos. La memoria de almacenamiento dinámico (requerida con vector ) requiere una llamada al sistema para asignar memoria y esto puede ser costoso si está contando ciclos. La memoria de la pila (posible para la array ) es virtualmente una "sobrecarga cero" en términos de tiempo, porque la memoria se asigna simplemente ajustando el puntero de la pila y se realiza solo una vez al ingresar a una función. La pila también evita la fragmentación de la memoria. Para estar seguro, std::array no siempre estará en la pila; depende de dónde lo asigne, pero aún implicará una asignación de memoria menos del montón en comparación con el vector. Si tienes un

  • "matriz" pequeña (por debajo de 100 elementos, por ejemplo) - (una pila típica es de aproximadamente 8 MB, así que no asigne más de unos pocos KB en la pila o si su código es recursivo)
  • el tamaño será fijo
  • el tiempo de vida está en el ámbito de la función (o es un valor miembro con el mismo tiempo de vida que la clase principal)
  • estás contando ciclos,

Definitivamente usa un std::array sobre un vector. Si alguno de esos requisitos no es verdadero, entonces use un std::vector .


Si está considerando utilizar matrices multidimensionales, entonces hay una diferencia adicional entre std :: array y std :: vector. Un std :: array multidimensional tendrá los elementos empaquetados en la memoria en todas las dimensiones, tal como lo es el array de estilo CA. Un std :: vector multidimensional no se empaquetará en todas las dimensiones.

Dadas las siguientes declaraciones:

int cConc[3][5]; std::array<std::array<int, 5>, 3> aConc; int **ptrConc; // initialized to [3][5] via new and destructed via delete std::vector<std::vector<int>> vConc; // initialized to [3][5]

Un puntero al primer elemento de la matriz de estilo c (cConc) o std :: array (aConc) se puede iterar a través de toda la matriz agregando 1 a cada elemento precedente. Están bien embalados.

Un puntero al primer elemento de la matriz de vectores (vConc) o la matriz de punteros (ptrConc) solo se puede iterar a través de los primeros 5 elementos (en este caso), y luego hay 12 bytes (en mi sistema) de sobrecarga para el siguiente vector

Esto significa que una matriz std :: vector> inicializada como una matriz [3] [1000] será mucho más pequeña en la memoria que una matriz inicializada como una matriz [1000] [3], y ambas serán más grandes en la memoria que una estándar: matriz asignada de cualquier manera.

Esto también significa que no puede simplemente pasar una matriz de vector (o puntero) multidimensional a, por ejemplo, openGL sin tener en cuenta la sobrecarga de memoria, pero puede pasar ingenuamente una matriz std :: array multidimensional a openGL y hacer que funcione.


Un vector es una clase contenedora mientras que una matriz es una memoria asignada.


Una de las ventajas que tienen los vectores sobre las matrices es que es posible encontrar el tamaño actual de un vector utilizando vector_name.size () .

Como puede imaginar, esto puede ser muy útil en una variedad de situaciones, donde puede obtener fácilmente el número de elementos en la lista de arreglos.


Usando la clase std::vector<T> :

  • ... es tan rápido como usar matrices integradas, asumiendo que usted está haciendo solo lo que las matrices integradas le permiten hacer (leer y escribir en elementos existentes).

  • ... automáticamente cambia de tamaño cuando se insertan nuevos elementos.

  • ... le permite insertar nuevos elementos al principio o en la mitad del vector, "cambiando" automáticamente el resto de los elementos "hacia arriba" (¿tiene sentido?). También le permite eliminar elementos en cualquier parte del std::vector , desplazando automáticamente el resto de los elementos hacia abajo.

  • ... le permite realizar una lectura de rango comprobado con el método at() (siempre puede usar los indexadores [] si no desea que se realice esta comprobación).

Hay dos tres advertencias principales sobre el uso de std::vector<T> :

  1. No tiene acceso confiable al puntero subyacente, lo que puede ser un problema si está tratando con funciones de terceros que exigen la dirección de una matriz.

  2. La clase std::vector<bool> es tonta. Se implementa como un campo de bits condensado, no como una matriz. ¡Evítalo si quieres una variedad de bool !

  3. Durante el uso, std::vector<T> s será un poco más grande que una matriz C ++ con el mismo número de elementos. Esto se debe a que necesitan realizar un seguimiento de una pequeña cantidad de otra información, como su tamaño actual, y porque cada vez que std::vector<T> cambia de tamaño, reservan más espacio del que necesitan. Esto es para evitar que tengan que cambiar el tamaño cada vez que se inserta un nuevo elemento. Este comportamiento se puede cambiar proporcionando un allocator personalizado, ¡pero nunca sentí la necesidad de hacerlo!

Edit: Después de leer la respuesta de Zud a la pregunta, sentí que debía agregar esto:

La clase std::array<T> no es lo mismo que una matriz C ++. std::array<T> es una envoltura muy delgada alrededor de matrices C ++, con el propósito principal de ocultar el puntero al usuario de la clase (en C ++, las matrices se lanzan implícitamente como punteros, a menudo con un efecto desalentador). La clase std::array<T> también almacena su tamaño (longitud), lo que puede ser muy útil.


std::vector es una clase de plantilla que encapsula una matriz dinámica 1 , almacenada en el montón, que crece y se contrae automáticamente si se agregan o eliminan elementos. Proporciona todos los ganchos ( begin() , end() , iteradores, etc.) que hacen que funcione bien con el resto de la STL. También tiene varios métodos útiles que le permiten realizar operaciones que en una matriz normal serían engorrosas, como, por ejemplo, insertar elementos en el medio de un vector (maneja todo el trabajo de mover los siguientes elementos detrás de escena).

Dado que almacena los elementos en la memoria asignada en el montón, tiene cierta sobrecarga con respecto a las matrices estáticas.

std::array es una clase de plantilla que encapsula una matriz de tamaño estático, almacenada dentro del propio objeto, lo que significa que, si crea una instancia de la clase en la pila, la matriz estará en la pila. Su tamaño se debe conocer en el momento de la compilación (se pasa como un parámetro de plantilla) y no puede aumentar o disminuir.

Es más limitado que std::vector , pero a menudo es más eficiente, especialmente para tamaños pequeños, porque en la práctica es sobre todo una envoltura ligera alrededor de una matriz de estilo C. Sin embargo, es más seguro, ya que la conversión implícita a puntero está deshabilitada y proporciona gran parte de la funcionalidad relacionada con STL de std::vector y de los otros contenedores, por lo que puede usarla fácilmente con los algoritmos STL & co. De todos modos, debido a la limitación del tamaño fijo, es mucho menos flexible que std::vector .

Para una introducción a std::array , eche un vistazo a este artículo ; para una introducción rápida a std::vector y a las operaciones que se pueden realizar en él, puede consultar su documentation .

  1. En realidad, creo que en el estándar se describen en términos de la máxima complejidad de las diferentes operaciones (por ejemplo, acceso aleatorio en tiempo constante, iteración sobre todos los elementos en tiempo lineal, adición y eliminación de elementos al final en tiempo amortizado constante, etc), pero AFAIK no existe otro método para cumplir con dichos requisitos, excepto el uso de una matriz dinámica. Como lo indica @Lucretiel, el estándar en realidad requiere que los elementos se almacenen de forma contigua, por lo que es una matriz dinámica, almacenada donde el asignador asociado lo coloca.