199 votes

Y a-t-il une limite de longueur maximale du tableau en C++ ?

Y a-t-il une longueur maximale pour un tableau en C++?

S'agit-il d'une limite en C++ ou cela dépend-il de ma machine? Est-ce modifiable? Est-ce en fonction du type de données utilisé pour le tableau?

Puis-je contourner cette limite d'une manière ou d'une autre ou dois-je chercher un meilleur moyen de stocker les informations? Et quel serait le moyen le plus simple?

Mon objectif est de stocker de longues valeurs de type long long int dans un tableau, je travaille dans un environnement Linux. Ma question est : que dois-je faire si j'ai besoin de stocker un tableau de N longs entiers longs avec N> 10 chiffres?

J'ai besoin de cela car je suis en train d'écrire un algorithme cryptographique (comme par exemple le p-Pollard) pour l'école, et je me heurte à ce mur des entiers et de la représentation de la longueur des tableaux.

186voto

Loki Astari Points 116129

Personne n'a mentionné la limite de la taille du cadre de pile.

Il y a deux endroits où la mémoire peut être allouée:

  • Sur le tas (mémoire allouée dynamiquement).
    La limite de taille ici est une combinaison du matériel disponible et de la capacité du système d'exploitation à simuler de l'espace en utilisant d'autres dispositifs pour stocker temporairement les données inutilisées (c.-à-d. déplacer des pages vers le disque dur).
  • Sur la pile (variables déclarées localement).
    La limite de taille ici est définie par le compilateur (avec d'éventuelles limites matérielles). Si vous lisez la documentation du compilateur, vous pouvez souvent ajuster cette taille.

Ainsi, si vous allouez un tableau de manière dynamique (la limite est large et décrite en détail dans d'autres publications).

int* a1 = new int[SIZE];  // SIZE limitée uniquement par le SE/Système Hardware

Alternativement, si le tableau est alloué sur la pile, vous êtes limité par la taille du cadre de pile. N.B. les vecteurs et autres conteneurs ont une petite présence sur la pile mais généralement la majeure partie des données sera sur le tas.

int a2[SIZE]; // SIZE limitée par le COMPILATEUR à la taille du cadre de pile

5 votes

L'allocation préférée des grands tableaux ne se fait pas sur une pile ou de manière globalement définie, mais plutôt par allocation dynamique (via new ou malloc).

2 votes

@Thomas Matthews : Pas dans mon monde. Les objets alloués dynamiquement nécessitent une gestion. Si cela doit être alloué dynamiquement, j'utiliserais un objet pile qui représente la mémoire allouée dynamiquement, comme un std::vector.

0 votes

@LokiAstari int* a1 = new int[SIZE]

173voto

Konrad Rudolph Points 231505

Il y a deux limites, toutes deux non imposées par C++ mais plutôt par le matériel.

La première limite (qui ne devrait jamais être atteinte) est fixée par les restrictions de la taille du type utilisé pour décrire un index dans le tableau (et sa taille). Elle est donnée par la valeur maximale que le type std::size_t du système peut prendre. Ce type de données est assez grand pour contenir la taille en octets de n'importe quel objet

L'autre limite est une limite de mémoire physique. Plus vos objets dans le tableau sont grands, plus cette limite est atteinte rapidement car la mémoire est pleine. Par exemple, un vector d'une taille donnée n prend généralement plusieurs fois plus de mémoire qu'un tableau de type vector (moins une petite valeur constante), puisque int est généralement plus grand que char. Par conséquent, un vector peut contenir plus d'éléments qu'un vector avant que la mémoire ne soit pleine. Il en va de même pour les tableaux de style C brut comme int[] et char[].

De plus, cette limite supérieure peut être influencée par le type d'allocator utilisé pour construire le vector car un allocator est libre de gérer la mémoire de la manière qu'il veut. Un allocator très étrange mais néanmoins concevable pourrait regrouper la mémoire de telle manière que des instances identiques d'un objet partagent des ressources. De cette manière, vous pourriez insérer beaucoup d'objets identiques dans un conteneur qui sinon utiliserait toute la mémoire disponible.

En dehors de cela, C++ n'impose aucune limite.

20 votes

Aussi, vous pouvez généralement atteindre facilement les limites de la taille de la pile, surtout si vous utilisez des threads, ce qui est encore une fois spécifique à l'implémentation (mais peut être modifié).

0 votes

@Alaric: Vrai. Je ne voulais pas entrer trop dans les détails spécifiques du système car ils sont très différents et je ne suis expert dans aucun d'entre eux.

0 votes

@Konrad, point intéressant sur les types d'allocateurs et pas quelque chose dont j'étais conscient. Merci pour l'info.

13voto

Shane MacLaughlin Points 12765

En le regardant d'un point de vue pratique plutôt que théorique, sur un système Windows 32 bits, la quantité totale maximale de mémoire disponible pour un seul processus est de 2 Go. Vous pouvez dépasser la limite en passant à un système d'exploitation 64 bits avec beaucoup plus de mémoire physique, mais que vous choisissiez de le faire ou de chercher des alternatives dépend beaucoup de vos utilisateurs prévus et de leurs budgets. Vous pouvez également l'étendre quelque peu en utilisant PAE.

Le type du tableau est très important, car la structure d'alignement par défaut sur de nombreux compilateurs est de 8 octets, ce qui est très gaspilleur si l'utilisation de mémoire est un problème. Si vous utilisez Visual C++ pour cibler Windows, consultez la directive #pragma pack comme moyen de surmonter cela.

Une autre chose à faire est de regarder quelles techniques de compression en mémoire pourraient vous aider, telles que les matrices creuses, la compression à la volée, etc... Encore une fois, cela dépend beaucoup de l'application. Si vous éditez votre message pour donner plus d'informations sur ce qui se trouve réellement dans vos tableaux, vous pourriez obtenir des réponses plus utiles.

Édition : Compte tenu de quelques informations supplémentaires sur vos exigences exactes, vos besoins de stockage semblent se situer entre 7,6 Go et 76 Go non compressés, ce qui nécessiterait une boîte 64 bits assez coûteuse pour stocker un tableau en mémoire en C++. Cela soulève la question de pourquoi vous voulez stocker les données en mémoire, où l'on présume pour la rapidité d'accès et pour permettre un accès aléatoire. La meilleure façon de stocker ces données en dehors d'un tableau dépend surtout de la manière dont vous souhaitez y accéder. Si vous avez besoin d'accéder de manière aléatoire aux membres du tableau, pour la plupart des applications, il y a tendance à être des moyens de regrouper des tas de données qui ont tendance à être accessibles en même temps. Par exemple, dans de grandes bases de données GIS et spatiales, les données sont souvent divisées en tuiles par zone géographique. En termes de programmation C++, vous pouvez remplacer l'opérateur [] du tableau pour extraire des portions de vos données à partir d'un stockage externe au besoin.

1 votes

Il existe des appels système qui permettent l'allocation de mémoire en dehors de l'espace du programme; mais cela dépend du système d'exploitation et n'est pas portable. Nous les avons utilisés dans les systèmes embarqués.

4voto

Tarski Points 2671

Je serais d'accord avec ce qui précède, selon lequel si vous initialisez votre tableau avec

 int myArray[SIZE]

alors SIZE est limité par la taille d'un entier. Mais vous pouvez toujours allouer dynamiquement un morceau de mémoire et avoir un pointeur vers celui-ci, aussi grand que vous le souhaitez tant que malloc ne retourne pas NULL.

1 votes

Je ne suis pas sûr que ce soit incorrect, ou si je vous ai mal compris, ou autre chose. Par exemple, cela est empêché par le compilateur MSVC17 : int oops[INT_MAX]{0}; Il génère, C2148 - la taille totale du tableau ne doit pas dépasser 0x7fffffff octets

0 votes

Avec 16 Go de DDR4 et environ 66% de mémoire actuellement utilisée avant le lancement de mon application en mode débogage sur Windows 10 avec VS2017, je n'ai pas de limite définie sur la taille maximale d'un tableau d'entiers que je peux initialiser avec 0. Parfois je peux le faire avec ~257k éléments, parfois j'obtiens un dépassement de pile. Si j'ajoute quelque chose à mon application en plus du programme principal et du tableau, ce nombre diminue (évidemment). J'ai dû expérimenter pour déterminer ce nombre, donc je ne vois pas comment cette mesure peut être fiable au-delà de connaître vos limites théoriques dans le vide.

2voto

Rob Wells Points 21714

Une chose que je ne pense pas avoir été mentionnée dans les réponses précédentes.

Je sens toujours une "mauvaise odeur" dans le sens du refactoring lorsque les gens utilisent de telles choses dans leur conception.

C'est un tableau énorme et peut-être pas la meilleure façon de représenter vos données à la fois du point de vue de l'efficacité et du point de vue des performances.

Santé,

Rob

0 votes

Avez-vous des suggestions sur ce que je devrais utiliser?

0 votes

Si vous pouvez nous dire quelles données vous stockez, peut-être que nous pourrons vous aider. (-:

0 votes

Désolé Luis, ma première réponse était trop légère. Cela dépendra de la nature de vos données. Les relations de vos données détermineront le modèle que vous utiliserez pour représenter les données. Ensuite, la collection devrait être évidente à partir de cela. Sinon, je m'inquiéterais du modèle de données.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X