C++ vector vs array: ¿cuál deberías usar?

Primero la respuesta corta, luego los detalles que sí importan en una entrevista y en código real.

La respuesta en 10 segundos

Por defecto, std::vector. Usa un array estilo C solo cuando el tamaño fijo forme parte del problema — y aun así prefiere std::array antes que el array crudo. Todo lo de abajo explica el porqué, porque «usa vector y ya» no sobrevive a la primera pregunta de seguimiento.

Tres contenedores, una misma idea

Array estilo Cstd::arraystd::vector
TamañoFijo en tiempo de compilaciónFijo en tiempo de compilaciónCrece y se encoge en ejecución
¿Dónde vive?Donde lo declares (en la pila si es local)Donde lo declaresLos datos en el heap; el objeto puede vivir en cualquier parte
¿Sabe su longitud?No — la llevas tú aparteSí — .size()Sí — .size()
¿Se puede copiar?No (decae a puntero)SíSí
Pasarlo a una funciónIncómodo (se convierte en puntero y se pierde el tamaño)LimpioLimpio
Comprobación de límitesNinguna.at() comprueba.at() comprueba, [] no

Cómo se ve cada uno

#include <array>
#include <vector>

int main() {
    int raw[5] = {1, 2, 3, 4, 5};               // estilo C: el tamaño es parte del tipo
    std::array<int, 5> fijo = {1, 2, 3, 4, 5};  // tamaño fijo, pero es un tipo de verdad
    std::vector<int> crece = {1, 2, 3};         // redimensionable

    crece.push_back(4);                         // ahora contiene 1 2 3 4
    return 0;
}

Nota: nuestro editor en el navegador cubre hoy el núcleo para principiantes (iostream, cmath, cstdio…), así que fragmentos como este pruébalos en tu compilador de escritorio — o en el editor cuando llegue el soporte completo de contenedores.

Por qué vector gana por defecto

Cuándo un array (de tamaño fijo) es de verdad mejor

Preguntas de seguimiento que conviene tener preparadas

  1. «¿Cómo crece un vector?» Al llenarse reserva un bloque mayor (habitualmente ~1,5× o 2×) y mueve los elementos — por eso push_back repetido sigue siendo O(1) amortizado.
  2. «¿Qué es vector<bool>?» Una pregunta trampa: es una especialización que empaqueta bits y no se comporta como un vector normal de valores.
  3. «¿Diferencia entre size() y capacity()?» size() = elementos en uso; capacity() = huecos reservados antes del siguiente crecimiento.
  4. «¿Un vector puede invalidar punteros?» Sí — cualquier crecimiento o insert/erase puede mover el almacenamiento. No guardes punteros ni referencias al interior de un vector y luego lo modifiques.

Regla práctica

Escribe std::vector hasta que tengas una razón medida para no hacerlo. ¿Tamaño fijo por naturaleza? Usa std::array. Los arrays crudos de C son para hablar con código C y para trabajo embebido con memoria ajustada — y aun ahí, envueltos.