¿Cuál es la diferencia entre un std::vector y un std::array en C++? Cuando debería ser preferido sobre otro? ¿Cuáles son los pros y los contras de cada uno? Todos mis libros de texto no es la lista de cómo son iguales.

  • Estoy buscando una comparación de std::vector vs std::array y cómo los términos son diferentes.
  • Zud, std::array no es el mismo que el de un C++ matriz. std::array es muy delgada envoltura alrededor de C++ matrices, con el principal propósito de ocultar el puntero del usuario de la clase. Voy a actualizar mi respuesta.
  • He actualizado a la pregunta del título y el texto para reflejar su aclaración.
InformationsquelleAutor Zud | 2010-12-12

5 Comentarios

  1. 288

    std::vector es una clase de plantilla que encapsulan una matriz dinámica1, almacenados en el montón, que crece y se contrae automáticamente si los elementos se agregan o se quitan. 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ía engorroso, como por ejemplo, la inserción de elementos en el medio de un vector (que se encarga de todo el trabajo de mover los siguientes elementos detrás de las escenas).

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

    std::array es una clase de plantilla que encapsulan un estáticamente matriz de tamaño, almacenada en el interior del objeto en sí mismo, lo que significa que, si se crea la instancia de la clase en la pila, la propia matriz estará en la pila. Su tamaño ha de ser conocido en tiempo de compilación (se pasa como un parámetro de plantilla), y no puede crecer o decrecer.

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

    Para una introducción a la std::array, eche un vistazo a este artículo; para una introducción rápida a std::vector y a las operaciones que son posibles en él, usted puede desear mirar en su documentación.


    1. en Realidad, creo que en la norma se describen en términos de máxima complejidad de las diferentes operaciones (por ejemplo, de acceso aleatorio en tiempo constante, la iteración a través de todos los elementos en el tiempo lineal, adición y eliminación de elementos en la final en constante amortizado tiempo, etc), pero AFAIK no hay ningún otro método de cumplimiento de tales requisitos distintos de los que utilizan una matriz dinámica. Como dijo @Lucretiel, el estándar requiere que los elementos se almacenan de forma contigua, por lo que es una matriz dinámica, donde se almacenan los asociados asignador pone.
    • Con respecto a su nota de pie de página: si bien es cierto, la norma también guarentees que la aritmética de punteros en el interior de los elementos de las obras, lo que significa que no tiene que ser una matriz: &vec[9] – &vec[3] == 6 es cierto.
    • Estoy bastante seguro de que, de que el vector no se reduzca automáticamente, pero debido a que C++11 puede llamar shrink_to_fit.
    • Estoy totalmente confundido por el término matriz estática y no estoy seguro de cuál es la terminología correcta es. Te refieres a una estática tamaño de la matriz y no una variable estática de la matriz (uno con almacenamiento estático). stackoverflow.com/questions/2672085/…. ¿Cuál es la terminología correcta? Es estática de la matriz de un descuidado plazo para un array con un tamaño fijo?
    • Me refiero a una forma estáticatamaño array, lo siento, estoy de acuerdo en que la terminología es confusa, voy a solucionarlo de inmediato.
    • bueno, por lo que no sólo para mí. No estoy tratando de ser pedante. Es sólo que he leído un x86 manual de montaje recientemente y se utiliza una matriz estática como se define en los datos/BSS sección, pero parece que en LO que la mayoría de preguntas/respuestas asumir una matriz estática automático es una variable de matriz.
    • definitivamente, no solo a ustedes, static es bastante maltratada plazo; el muy static palabra clave en C++ tiene tres diferentes sin relación de significados, y el término también se utiliza a menudo para hablar de cosas que se fija en tiempo de compilación. Espero que «estáticamente tamaño» es un poco más claro.
    • no garantiza una reducción, se puede reducir el vector, pero no es 100% garantizado.
    • sería el rendimiento de vector de ser comparable a la de la matriz, si ambos están en el montón?
    • Una cosa a tener en cuenta: tiempo real programación (donde no debes tener cualquier dinámica de asignación/desasignación después del inicio) std::matriz probablemente sería preferible std::vector.
    • No puedo entender cómo el banco de marca muestra contrario.

  2. 15

    El uso de la std::vector<T> clase:

    • …es tan rápido como el uso integrado de las matrices, suponiendo que solo están haciendo las cosas incorporados en matrices que permiten hacer (leer y escribir a los elementos existentes).

    • …redimensiona automáticamente cuando nuevos elementos se insertan.

    • …permite insertar nuevos elementos al principio o en el medio del vector, de forma automática «cambio» en el resto de los elementos de «seguridad» (¿eso tiene sentido?). Permite eliminar elementos en cualquier lugar en el std::vector, también, automáticamente, cambiando el resto de los elementos.

    • …permite realizar una amplia gama marcada de leer con el at() método (que siempre puede utilizar los indexadores [] si usted no desea que esta verificación se realiza).

    Hay dos tres razones principales para usar std::vector<T>:

    1. Usted no tiene acceso seguro a la base del puntero, que puede ser un problema si usted está tratando con terceros las funciones que demanda la dirección de una matriz.

    2. La std::vector<bool> clase es una tontería. Se implementa como un condensado campo de bits, no como una matriz. Evitar si quieres una matriz de bools!

    3. Durante el uso, std::vector<T>s va a ser un poco más grande que la de C++ matriz con el mismo número de elementos. Esto es debido a que necesitan para seguir la pista de una pequeña cantidad de otra información, tales como su tamaño actual, y porque siempre std::vector<T>s cambiar el tamaño, se reserva más espacio que necesitan. Esto es para evitar de tener que cambiar el tamaño de cada vez que un nuevo elemento se inserta. Este comportamiento puede ser cambiado por proporcionar una costumbre allocator, pero yo nunca sentí la necesidad de hacer eso!


    Edit: Después de la lectura Es la respuesta a la pregunta, sentí que debía añadir esto:

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

    • Es «tan rápido» como el uso de un asignados de forma dinámica integrada en la matriz. Por otro lado, el uso de un sistema automático de matriz puede tener de forma considerable el rendimiento (y no sólo durante la asignación, debido a los efectos de la localidad).
    • Para los no-bool vectores en C++11 y más tarde, usted puede llamar a data() en un std::vector<T> para obtener el subyacente puntero. Usted también puede tomar la dirección de elemento 0 (garantizado para trabajar con C++11, probablemente funcione con versiones anteriores).
    • Cómo acerca de este parámetro?
  3. 14

    Para enfatizar un punto hecho por @MatteoItalia, la eficiencia diferencia es donde se almacenan los datos. La memoria Heap (requerido con vector) requiere una llamada al sistema para asignar memoria y esto puede ser costoso si usted está contando los ciclos. Memoria de pila (posible para array) es prácticamente cero «sobrecarga» en términos de tiempo, porque la memoria es asignada por sólo ajuste el puntero de la pila y se realiza sólo una vez en la entrada a una función. La pila también se evita la fragmentación de la memoria. Para estar seguro, std::array no siempre estará en la pila; depende de dónde asignar, pero aún así involucrar a un menor en la asignación de memoria de la pila en comparación con el vector. Si usted tiene un

    • pequeño «matriz» (por debajo de 100 elementos decir) – (típico de la pila es de aproximadamente 8 MB, así que no asignar más de un par de KB en la pila o menos si su código es recursivo)
    • el tamaño será fijo
    • la vida es en el ámbito de la función (o un miembro de valor con la misma vida útil que los padres de clase)
    • usted está contando los ciclos,

    definitivamente std::array más de un vector. Si alguno de estos requisitos no es cierto, entonces el uso de un std::vector.

    • Bonita respuesta. «Para estar seguro, std::matriz no siempre estará en la pila; depende de dónde asignar» Entonces, ¿cómo podría yo crear un std::array no en la pila con un gran número de elementos?
    • uso new std::array o hacer que un miembro de una clase que utilice ‘nuevo` para asignar.
    • Así que esto significa new std::array todavía espera a conocer su tamaño en tiempo de compilación y no se puede cambiar su tamaño, pero aún vive en el montón?
    • Sí. No hay una ventaja significativa para el uso de new std::array vs new std::vector.
  4. 10

    Si usted está considerando el uso de matrices multidimensionales, entonces hay una diferencia adicional entre std::array y std::vector. Multidimensional std::matriz no tendrá los elementos de lleno en la memoria de todas las dimensiones, así como un estilo de c matriz. Multidimensional std::vector no será embalado 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 en el estilo c de la matriz (cConc) o el std::array (aConc) se puede iterar a través de toda la matriz mediante la adición de 1 a cada elemento precedente. Están apretadas.

    Un puntero al primer elemento del vector de la matriz (vConc) o el puntero de la matriz (ptrConc) sólo puede recorrerse a través de los primeros 5 (en este caso) de los elementos y, a continuación, hay 12 bytes (en mi sistema) de los gastos generales para el siguiente vector.

    Esto significa que un std::vector> array inicializado como [3][1000] matriz será mucho más pequeño en la memoria de un inicializa como [1000][3] matriz, y ambos serán más grandes en la memoria de un std:matriz asignados en forma.

    Esto también significa que usted no puede simplemente pasar un vector multidimensional (o puntero) de la matriz a, digamos, openGL sin tomar en cuenta la sobrecarga de la memoria, pero usted puede simplemente pasar un multidimensionales std::matriz de openGL y que funcionen.

  5. -16

    Un vector es una clase de contenedor, mientras que una matriz es una memoria asignada.

    • Su respuesta parece a la dirección de std::vector<T> frente a T[], pero la pregunta es acerca de std::vector<T> frente a std::array<T>.

Dejar respuesta

Please enter your comment!
Please enter your name here