web-dev-qa-db-fra.com

Combien de caractères peuvent être dans un tableau de caractères?

#define HUGE_NUMBER ???

char string[HUGE_NUMBER];
do_something_with_the_string(string);

Je me demandais quel serait le nombre maximum que je pourrais ajouter à un tableau de caractères sans risquer de problèmes de mémoire potentiels, de débordements de tampon ou similaires. Je voulais obtenir la contribution de l'utilisateur, et peut-être le maximum possible.

20
user666010

Voir cette réponse de Jack Klein (voir article d'origine ):

La norme C d'origine (ANSI 1989/ISO 1990) exigeait qu'un compilateur traduise avec succès au moins un programme contenant au moins un exemple d'un ensemble de limites environnementales. L'une de ces limites était la possibilité de créer un objet d'au moins 32 767 octets.

Cette limite minimale a été relevée dans la mise à jour de 1999 de la norme C pour être d'au moins 65 535 octets.

Aucune implémentation C n'est requise pour fournir des objets supérieurs à cette taille, ce qui signifie qu'ils n'ont pas besoin de permettre un tableau d'entiers supérieur à (int) (65535/sizeof (int)).

En termes très pratiques, sur les ordinateurs modernes, il n'est pas possible de dire à l'avance la taille d'une baie pouvant être créée. Cela peut dépendre de choses telles que la quantité de mémoire physique installée sur l'ordinateur, la quantité de mémoire virtuelle fournie par le système d'exploitation, le nombre d'autres tâches, pilotes et programmes déjà en cours d'exécution et la quantité de mémoire utilisée. Ainsi, votre programme pourra peut-être utiliser plus ou moins de mémoire en cours d'exécution aujourd'hui qu'il ne pouvait en utiliser hier ou il pourra l'utiliser demain.

De nombreuses plates-formes imposent leurs limites les plus strictes aux objets automatiques, c'est-à-dire ceux définis à l'intérieur d'une fonction sans utiliser le mot clé 'statique'. Sur certaines plateformes, vous pouvez créer des tableaux plus grands s'ils sont statiques ou par allocation dynamique.

Maintenant, pour fournir une réponse légèrement plus personnalisée, NE DÉCLAREZ PAS D'ÉNORMES TABLEAUX POUR ÉVITER LES DÉBORDEMENTS DE TAMPON . C'est proche de la pire pratique à laquelle on puisse penser en C. Plutôt, passez du temps à écrire du bon code et assurez-vous soigneusement qu'aucun débordement de tampon ne se produira. De plus, si vous ne connaissez pas la taille de votre tableau à l'avance, regardez malloc, cela pourrait vous être utile: P

14
Greg

Cela dépend de l'endroit où char string[HUGE_NUMBER]; est placé.

  • Est-ce à l'intérieur d'une fonction? Ensuite, le tableau sera sur la pile, et si et à quelle vitesse votre système d'exploitation peut augmenter les piles dépend du système d'exploitation. Voici donc la règle générale: ne placez pas d'énormes tableaux sur la pile.

  • Est-ce en dehors d'une fonction, alors elle est globale (mémoire de processus), si le système d'exploitation ne peut pas allouer autant de mémoire lorsqu'il essaie de charger votre programme, votre programme se bloquera et votre programme n'aura aucune chance de le remarquer (donc ce qui suit est mieux:)

  • Les grands tableaux doivent être malloc 'ed. Avec malloc, le système d'exploitation renverra un pointeur nul si le malloc a échoué, en fonction du système d'exploitation et de son schéma de pagination et de schéma de mappage de mémoire, cela échouera lorsque 1) il n'y a pas de région continue de libre mémoire suffisamment grande pour la baie ou 2) le système d'exploitation ne peut pas mapper suffisamment de régions de mémoire physique libre à la mémoire qui apparaît à votre processus comme une mémoire continue.

Donc, avec de grands tableaux, procédez comme suit:

char* largeArray = malloc(HUGE_NUMBER);
if(!largeArray) { do error recovery and display msg to user }
7
Bernd Elkemann

Déclarer des tableaux arbitrairement énormes pour éviter les débordements de tampon est une mauvaise pratique. Si vous ne savez vraiment pas à l'avance la taille d'un tampon, utilisez malloc ou realloc pour allouer et étendre dynamiquement le tampon si nécessaire, en utilisant éventuellement un tampon plus petit et de taille fixe comme intermédiaire.

Exemple:

#define PAGE_SIZE 1024  // 1K buffer; you can make this larger or smaller

/**
 * Read up to the next newline character from the specified stream.
 * Dynamically allocate and extend a buffer as necessary to hold
 * the line contents.
 *
 * The final size of the generated buffer is written to bufferSize.
 * 
 * Returns NULL if the buffer cannot be allocated or if extending it
 * fails.
 */
 char *getNextLine(FILE *stream, size_t *bufferSize)
 {
   char input[PAGE_SIZE];  // allocate 
   int done = 0;
   char *targetBuffer = NULL;
   *bufferSize = 0;

   while (!done)
   {
     if(fgets(input, sizeof input, stream) != NULL)
     {
       char *tmp;
       char *newline = strchr(input, '\n');
       if (newline != NULL)
       {
         done = 1;
         *newline = 0;
       }
       tmp = realloc(targetBuffer, sizeof *tmp * (*bufferSize + strlen(input)));
       if (tmp)
       {
         targetBuffer = tmp;
         *bufferSize += strlen(input);
         strcat(targetBuffer, input);
       }
       else
       {
         free(targetBuffer);
         targetBuffer = NULL;
         *bufferSize = 0;
         fprintf(stderr, "Unable to allocate or extend input buffer\n");

       }
     }
   }
4
John Bode

Si le tableau va être alloué sur la pile, alors vous êtes limité par la taille de la pile ( généralement 1 Mo sous Windows , une partie de celui-ci sera utilisée pour en avoir encore moins). Sinon, j'imagine que la limite serait assez grande.

Cependant, rendre le tableau vraiment grand n'est pas une solution aux problèmes de dépassement de tampon . Ne le fais pas. Utilisez des fonctions qui ont un mécanisme pour limiter la quantité de tampon qu'elles utilisent pour vous assurer que vous ne dépassez pas votre tampon, et rendez la taille quelque chose de plus raisonnable (1K par exemple).

3
Jon

Vous pouvez utiliser malloc() pour obtenir des portions de mémoire plus grandes que normalement un tableau pourrait gérer.

1
vbence

Eh bien, un débordement de tampon ne serait pas causé par une valeur trop grande pour HUGE_NUMBER autant que trop petite par rapport à ce qui y était écrit (écrivez dans l'index HUGE_NUMBER ou supérieur, et vous avez survolé le tampon).

En dehors de cela, cela dépendra de la machine. Il y a certainement des systèmes qui pourraient gérer plusieurs millions dans le tas, et environ un million sur la pile (en fonction d'autres pressions), mais il y en a aussi certains qui ne pouvaient pas en gérer plus de quelques centaines (les petits appareils intégrés seraient un exemple évident). Alors que 65 535 est un minimum spécifié par la norme, un très petit appareil pourrait spécifier que la norme a été délibérément écartée pour cette raison.

En termes réels, sur une grande machine, bien avant de manquer de mémoire, vous exercez inutilement une pression sur la mémoire de manière à affecter les performances. Vous feriez mieux de dimensionner dynamiquement un tableau à une taille appropriée.

0
Jon Hanna