Saltar al contenido

¿Cuál es el tamaño máximo de un array ¿C ª?

Es imprescindible comprender el código de forma correcta previamente a utilizarlo a tu proyecto si tquieres aportar algo puedes dejarlo en los comentarios.

Solución:

No hay reparado limitar el tamaño de un array C ª.

El tamaño de cualquier objeto individual, incluso de cualquier array objeto, está limitado por SIZE_MAXel valor máximo de tipo size_tque es el resultado de la sizeof operador. (No está del todo claro si el estándar C permite objetos más grandes que SIZE_MAX bytes, pero en la práctica tales objetos no son compatibles; ver nota al pie.) Dado que SIZE_MAX está determinado por la implementación, y no puede ser modificado por ningún programa, que impone un límite superior de SIZE_MAX bytes para cualquier objeto individual. (Ese es un límite superior, no un límite superior mínimo; las implementaciones pueden, y normalmente lo hacen, imponer límites más pequeños).

El ancho del tipo void*un tipo de puntero genérico, impone un límite superior al tamaño total de todos los objetos en un programa en ejecución (que puede ser mayor que el tamaño máximo de un solo objeto).

El estándar C impone límites inferiores, pero no superiores, a estos tamaños fijos. Ninguna implementación C conforme puede admitir objetos de tamaño infinito, pero en principio puede admitir objetos de cualquier tamaño finito. Los límites superiores los imponen las implementaciones individuales de C, los entornos en los que operan y la física, no el lenguaje.

Por ejemplo, una implementación conforme podría tener SIZE_MAX igual a 21024-1, lo que significa que podría en principio tener objetos hasta 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215 bytes.

Buena suerte para encontrar hardware que realmente admita tales objetos.

Nota: No existe una regla explícita de que ningún objeto puede ser más grande que SIZE_MAX bytes No podrías aplicar de manera útil el sizeof operador a tal objeto, pero como cualquier otro operador, sizeof puede desbordarse; eso no significa que no pueda realizar operaciones en dicho objeto. Pero en la práctica, cualquier implementación sensata hará size_t lo suficientemente grande como para representar el tamaño de cualquier objeto que soporte.

C99 5.2.4.1 “Límites de traducción” tamaño mínimo

La implementación deberá poder traducir y ejecutar al menos un programa que contenga al menos una instancia de cada uno de los siguientes límites: 13)

  • 65535 bytes en un objeto (solo en un entorno alojado)
  1. Las implementaciones deben evitar imponer límites de traducción fijos siempre que sea posible.

Esto sugiere que una implementación conforme podría negarse a compilar un objeto (que incluye matrices) con más de short bytes

PTRDIFF_MAX también impone algunos límites array dice

El estándar C99 6.5.6 Operadores aditivos dice:

9 Cuando se resten dos punteros, ambos apuntarán a elementos del mismo array objeto, o uno más allá del último elemento del array objeto; el resultado es la diferencia de los subíndices de los dos array elementos. El tamaño del resultado está definido por la implementación y su tipo (un tipo entero con signo) es ptrdiff_t definido en el encabezamiento. Si el resultado no es representable en un objeto de ese tipo, el comportamiento no está definido.

Lo que implica para mí que las matrices más grandes que ptrdiff_t están permitidos en teoría, pero entonces no puede tomar la diferencia de sus direcciones de forma portátil.

Entonces, tal vez por esta razón, GCC parece limitarlo a ptrdiff_t. Esto también se menciona en: ¿Por qué el tamaño máximo de un array “demasiado grande”?

Experimentos

Tal vez lo que importa en última instancia es lo que acepte su compilador, así que aquí vamos:

C Principal

#include 

TYPE a[(NELEMS)];

int main(void) 
    return 0;

tallas.c

#include 
#include 

int main(void) 
    printf("PTRDIFF_MAX 0x%jxn", (uintmax_t)PTRDIFF_MAX);
    printf("SIZE_MAX    0x%jxn", (uintmax_t)SIZE_MAX);
    return 0;

Y luego tratamos de compilar con:

gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o sizes.out sizes.c
./sizes.out
gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out 
  -DNELEMS='((2lu << 62) - 1)' -DTYPE=uint8_t main.c 

Resultados:

  • PTRDIFF_MAX: 0x7fffffffffffffff = 2^63 - 1

  • TAMAÑO_MAX: 0xffffffffffffffff = 2^64 - 1

  • -DNELEMS='((2lu << 62) - 1)' -DTYPE=uint8_t: compila (== 2^63 - 1). Ejecutarlo segfaults inmediatamente en mi mero sistema de RAM de 32 GB :-)

  • -DNELEMS='(2lu << 62)' -DTYPE=uint8_t: la compilación falla con:

    error: size of array ‘a’ is too large
    
  • -DNELEMS='(2lu << 62 - 1)' -DTYPE=uint16_t: la compilación falla con:

    error: size ‘18446744073709551614’ of array ‘a’ exceeds maximum object size ‘9223372036854775807’
    

    donde 9223372036854775807 == 0x7fffffffffffffff

Entonces, de esto entendemos que GCC impone dos limitaciones con diferentes mensajes de error:

  • el número de elementos no puede exceder 2^63 (pasa a == PTRDIFF_MAX)
  • array el tamaño no puede exceder 2^63 (también sucede con == PTRDIFF_MAX)

Probado en Ubuntu 20.04 amd64, GCC 9.3.0.

Ver también

  • ¿Existen limitaciones de tamaño para las estructuras C?
  • ¿Cuál es el tipo correcto para array índices en C?

En teoría, una máquina de 64 bits podría abordar un máximo de 2^64 bytes de memoria.

Comentarios y valoraciones

Te invitamos a defender nuestro análisis fijando un comentario y valorándolo te lo agradecemos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *