Quelle est la taille maximale d'un tableau en C?

je comprends que le matériel limitera la quantité de mémoire allouée pendant l'exécution du programme. Cependant, ma question Est sans égard au matériel. en supposant qu'il n'y avait pas de limite à la quantité de mémoire, n'y aurait-il pas de limite au tableau?

38

7 réponses

il n'y a pas de fixe limite à la taille D'un tableau en C.

la taille de tout objet simple, y compris de tout objet array, est limitée par SIZE_MAX , la valeur maximale du type size_t , qui est le résultat de l'opérateur sizeof . (Il n'est pas tout à fait clair si la norme C autorise des objets de plus de SIZE_MAX octets, mais en pratique de tels objets ne sont pas pris en charge; voir la note de bas de page.) Depuis SIZE_MAX est déterminé par l'implémentation, et ne peut être modifié par aucun programme, qui impose une limite supérieure de SIZE_MAX octets pour tout objet simple. (C'est une limite supérieure, et non la moindre; les implémentations peuvent imposer des limites plus petites, et c'est généralement le cas.)

la largeur du type void* , un type de pointeur Générique, impose une limite supérieure à la taille totale de tous les objets dans un programme d'exécution (qui peut être plus grande que la taille maximale d'un seul objet).

la norme C impose des limites inférieures, mais pas supérieures, à ces dimensions fixes. Aucune implémentation C Conforme ne peut supporter des objets de taille infinie, mais elle peut en principe supporter des objets de taille finie. Les limites supérieures sont imposées par des implémentations C individuelles, par les environnements dans lesquels elles opèrent, et par la physique, et non par le langage.

par exemple, une implémentation conforme pourrait avoir SIZE_MAX égal à 2 1024 -1, ce qui signifie qu'il pourrait en principe avoir des objets jusqu'à 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215 bytes.

bonne chance pour trouver du matériel qui supporte réellement de tels objets.

note de bas de page : il n'existe pas de règle explicite selon laquelle aucun objet ne peut être plus grand que SIZE_MAX octets. Vous ne pouvez pas appliquer utilement l'opérateur sizeof à un tel objet, mais comme tout autre opérateur, sizeof peut déborder; cela ne signifie pas que vous ne pouvez pas effectuer des opérations sur un tel objet. Mais en pratique, n'importe quelle implémentation saine fera size_t assez grand pour représenter la taille de n'importe quel objet qu'il supporte.

37
répondu Keith Thompson 2018-03-23 16:04:19

C99 5.2.4.1" limites de Translation "dimensions minimales

"

L'implémentation doit pouvoir traduire et exécuter au moins un programme qui contient au moins une instance de chacune des limites suivantes: 13)

  • 65535 octets dans un objet (dans un environnement hébergé seulement)

13) les implémentations devraient éviter d'imposer une traduction fixe les limites de la mesure du possible.

cela suggère qu'une implémentation conforme pourrait refuser de compiler un objet (qui inclut des tableaux) avec plus de octets short .

PTRDIFF_MAX semble être une limite pratique pour tableau statique des objets

Le standard C99 6.5.6 Additif opérateurs dit:

9 lorsque deux les pointeurs sont soustraits, les deux doivent pointer vers des éléments du même objet de tableau, ou un après le dernier élément de l'objet array; le résultat est la différence de les indices des deux éléments du tableau. La taille du résultat est définie par la mise en œuvre, et son type (un type entier signé) est ptrdiff_t défini dans l'en-tête <stddef.h> . Si le résultat n'est pas représentable dans un objet de ce type, le comportement est indéfini.

qui implique pour moi que les tableaux plus grands que ptrdiff_t sont autorisés en théorie, mais alors vous ne pouvez pas prendre la différence de leurs adresses de manière portabile.

donc peut-être pour cette raison, GCC semble vous limiter à ptrdiff_t . Ceci est aussi mentionné: Pourquoi est la taille maximale d'un tableau est "trop grand"?

j'ai empiriquement vérifié avec main.c :

#include <stdint.h>

uint8_t a[(X)];

int main(void) {
    return 0;
}

puis dans Ubunbu 17.10:

$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.2.0-6ubuntu1) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ printf '
> #include <stdint.h>
> PTRDIFF_MAX
> SIZE_MAX
> ' | arm-linux-gnueabi-cpp | tail -n2
(2147483647)
(4294967295U)
$ PTRDIFF_MAX == 2147483647 == 2^31 - 1
$
$ # 2lu << 30 == 2^31 == PTRDIFF_MAX + 1
$ arm-linux-gnueabi-gcc -std=c99 -DX='(2lu << 30)' main.c
a.c:5:9: error: size of array ‘a’ is too large
 uint8_t a[(X)];
         ^
$
$ # PTRDIFF_MAX
$ arm-linux-gnueabi-gcc -std=c99 -DX='(2lu << 30) - 1lu' main.c
$

Voir aussi

7

une machine 64 bits pourrait théoriquement traiter un maximum de 2^64 octets de mémoire.

6
répondu greg 2012-02-21 23:35:33

sans égard à la mémoire, la taille maximale d'un tableau est limitée par le type d'entier utilisé pour indexer le tableau.

4
répondu Greg Hewgill 2012-02-21 23:35:21

je suppose que le plus grand tableau théorique serait la valeur max de "non signé long" (ou quel que soit le plus grand nombre entier la dernière norme / votre compilateur soutient)

2
répondu John3136 2012-02-21 23:34:36

la taille du pointeur limitera la mémoire à laquelle vous pouvez accéder. Même si le matériel offre la prise en charge de la mémoire illimitée, si le plus grand type de données que vous pouvez utiliser est 64 bits, vous ne pourrez accéder qu'à 2^64 octets de mémoire.

2
répondu Femaref 2012-02-21 23:36:00

je cherchais un moyen pour déterminer la taille maximale d'un tableau. Cette question semble poser la même question, alors je veux partager mes conclusions.

initialement, C ne fournit aucune fonction pour déterminer le nombre maximum d'éléments allocables dans un tableau en temps de compilation. C'est parce qu'il dépend de la mémoire disponible dans la machine où il sera exécuté.

d'autre part, j'ai trouvé, cette allocation de mémoire les fonctions ( calloc() et malloc() ) permettent d'attribuer des tableaux plus grands. De plus, ces fonctions vous permettent de gérer les erreurs d'allocation de mémoire d'exécution.

Espère que ça aide.

0
répondu Tony 2013-09-10 22:45:06