Menu

Arrays en C++: declaración, indexación y errores comunes

Los arrays nativos de C++ explicados: cómo declararlos e inicializarlos, indexar de forma segura, recorrerlos usando su tamaño, la trampa de la degradación de array a puntero y por qué std::array y vector suelen ser mejores.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Una fila de valores de tamaño fijo

Un array es un bloque contiguo de memoria que almacena un número fijo de valores del mismo tipo. Mientras que un único int guarda un número, un array de int guarda muchos seguidos, cada uno accesible mediante un índice entero.

Declaras uno indicando el tipo de los elementos, un nombre y un tamaño entre corchetes. Añade una lista entre llaves para rellenarlo:

La indexación empieza en cero: el primer elemento es scores[0], y un array de tamaño 4 tiene índices válidos del 0 al 3. El tamaño debe ser una constante en tiempo de compilación: no puedes escribir int n = readInput(); int a[n]; en C++ estándar (eso es una extensión no portable). Cuando necesitas un tamaño decidido en tiempo de ejecución, recurre a un vector en su lugar.

Inicializar arrays

Tienes varias formas de rellenar un array, y un par de atajos que conviene conocer:

El detalle que hay que interiorizar: cuando proporcionas menos inicializadores que el tamaño, los que faltan quedan inicializados por valor (cero para los tipos numéricos), no como basura. Pero un array sin ningún inicializador —int e[4]; declarado como variable local— contiene valores indeterminados, y leerlos antes de asignarlos es comportamiento indefinido.

Recorrer un array

Como los elementos se almacenan de forma contigua, recorres un array con un simple bucle por índice. Para no salirte de los límites, controla el bucle con la longitud real del array en lugar de con un número escrito a mano:

sizeof(scores) es el número total de bytes de todo el array; al dividirlo entre sizeof(scores[0]) (el tamaño de un elemento) obtienes la cantidad de elementos. Desde C++17 hay una forma más limpia, std::size(scores), que se lee mejor y se niega a compilar si por error le pasas un puntero. Aún más sencillo cuando solo necesitas los valores: un for basado en rango se salta por completo el cálculo de índices.

La trampa del acceso fuera de límites

C++ no comprueba los límites en arr[i]. Indexar más allá del último elemento no lanza una excepción ni avisa: lee o escribe en la memoria que haya en ese lugar. Este es el error de arrays más habitual, y es un caso clásico de comportamiento indefinido:

int a[3] = {1, 2, 3};
a[3] = 99;          // OOPS - valid indices are 0..2, not 3
cout << a[5];       // garbage, crash, or corruption - undefined behavior

El error de "uno de más" suele esconderse en la condición de un bucle. Escribir i <= n en lugar de i < n da un paso de más y toca arr[n], que no existe:

for (int i = 0; i <= n; i++)   // BUG: when i == n, arr[i] is out of bounds
    cout << arr[i];

La solución es la disciplina de la sección anterior: recorre con i < size, nunca con <=, y calcula el tamaño a partir del array en lugar de reescribir un literal que se desincroniza cuando añades un elemento.

La degradación de arrays: el puntero oculto

El comportamiento más complicado de los arrays en C++ es la degradación: cuando pasas un array a una función, se convierte silenciosamente en un puntero a su primer elemento. La información del tamaño se pierde, así que sizeof dentro de la función mide el puntero, no el array.

Ten en cuenta que int arr[] e int* arr son idénticos como parámetros de función: los corchetes son meramente cosméticos. Como la cantidad se pierde, debes pasar tú mismo la longitud junto con el array:

int sum(const int* arr, int n) {
    int total = 0;
    for (int i = 0; i < n; i++) total += arr[i];
    return total;
}

Este patrón de "pasa un puntero y una longitud, y reza para que coincidan" es justo la fricción que empuja a la mayoría del código C++ hacia std::array y std::vector, que llevan su propio tamaño y nunca se degradan.

Unas palabras sobre los arrays multidimensionales

Puedes anidar los corchetes para crear una cuadrícula. Un array 2D es en realidad un array de arrays, dispuesto fila por fila en memoria:

Lo indexas como grid[row][col]. Se aplican las mismas advertencias sobre límites y degradación —y empeoran, ya que pasar un array 2D a una función exige especificar todas las dimensiones excepto la primera (void f(int g[][3])). Para cualquier cosa más allá de una pequeña cuadrícula fija, un vector de vectors es mucho menos propenso a errores.

Siguiente: Vector

Los arrays nativos son rápidos y predecibles, pero su tamaño fijo, la falta de seguridad en los límites y su degradación a puntero los hacen incómodos para el código del día a día. A continuación conoceremos std::vector: un array redimensionable que crece bajo demanda, recuerda su propio tamaño y se integra directamente con los algoritmos de la STL, ofreciéndote casi todo lo que dan los arrays con muchas menos formas de pegarte un tiro en el pie.

Preguntas frecuentes

¿Cómo se declara e inicializa un array en C++?

Escribe el tipo de los elementos, un nombre y el tamaño entre corchetes y, opcionalmente, una lista entre llaves: int scores[4] = {90, 75, 100, 60};. Puedes omitir el tamaño cuando proporcionas inicializadores: int scores[] = {90, 75, 100, 60}; deja que el compilador los cuente por ti.

¿Cómo se obtiene la longitud de un array en C++?

Para un array real que sigue en su ámbito, usa std::size(arr) (C++17) o sizeof(arr) / sizeof(arr[0]). Esto no funciona una vez que el array se ha degradado a puntero (por ejemplo, dentro de una función que recibió int arr[]), donde sizeof devuelve el tamaño del puntero, no el del array.

¿Qué ocurre si accedes a un array fuera de límites en C++?

Es comportamiento indefinido. C++ no comprueba los límites en arr[i], así que leer o escribir más allá del final puede provocar un fallo, devolver basura o corromper en silencio la memoria cercana. Mantén siempre el índice en el rango 0 a size - 1.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR