Wie viele Zeichen können in einem Char-Array enthalten sein?

Lesezeit: 5 Minuten

Benutzer-Avatar
Benutzer666010

#define HUGE_NUMBER ???

char string[HUGE_NUMBER];
do_something_with_the_string(string);

Ich habe mich gefragt, was die maximale Anzahl wäre, die ich zu einem Char-Array hinzufügen könnte, ohne potenzielle Speicherprobleme, Pufferüberläufe oder ähnliches zu riskieren. Ich wollte Benutzereingaben erhalten, und zwar möglichst das Maximum.

  • Es hängt stark von dem C ab, das Sie verwenden, und von der Plattform, auf der Sie es kompilieren.

    – vbence

    18. März 2011 um 12:27 Uhr

Siehe diese Antwort von Jack Klein (siehe Originalbeitrag):

Der ursprüngliche C-Standard (ANSI 1989/ISO 1990) erforderte, dass ein Compiler mindestens ein Programm erfolgreich übersetzte, das mindestens ein Beispiel für eine Reihe von Umweltgrenzwerten enthielt. Eine dieser Einschränkungen bestand darin, ein Objekt mit mindestens 32.767 Bytes erstellen zu können.

Diese Mindestgrenze wurde in der Aktualisierung des C-Standards von 1999 auf mindestens 65.535 Byte angehoben.

Es ist keine C-Implementierung erforderlich, um Objekte bereitzustellen, die größer als diese Größe sind, was bedeutet, dass sie kein Array von Ganzzahlen größer als (int)(65535 / sizeof(int)) zulassen müssen.

Ganz praktisch kann man auf modernen Computern nicht im Voraus sagen, wie groß ein Array erstellt werden kann. Dies kann von Dingen wie der Menge des im Computer installierten physischen Speichers, der Menge des vom Betriebssystem bereitgestellten virtuellen Speichers, der Anzahl anderer Aufgaben, Treiber und Programme, die bereits ausgeführt werden, und der Menge des verwendeten Speichers abhängen. Ihr Programm kann also heute mehr oder weniger Arbeitsspeicher verbrauchen als gestern oder morgen.

Viele Plattformen legen ihre strengsten Grenzen für automatische Objekte fest, dh solche, die innerhalb einer Funktion ohne Verwendung des Schlüsselworts „static“ definiert werden. Auf einigen Plattformen können Sie größere Arrays erstellen, wenn sie statisch oder durch dynamische Zuweisung sind.

Um nun eine etwas individuellere Antwort zu geben, ERKLÄREN SIE KEINE RIESIGEN ARRAYS, UM PUFFERÜBERLÄUFE ZU VERMEIDEN. Das kommt der schlechtesten Praxis nahe, die man sich in C vorstellen kann. Verbringen Sie lieber etwas Zeit damit, guten Code zu schreiben, und stellen Sie sorgfältig sicher, dass kein Pufferüberlauf auftritt. Wenn Sie die Größe Ihres Arrays im Voraus nicht kennen, schauen Sie sich auch an malloces könnte nützlich sein 😛

Es kommt darauf an wo char string[HUGE_NUMBER]; ist plaziert.

  • Ist es in einer Funktion? Dann wird das Array auf dem Stapel sein, und wenn und wie schnell Ihr Betriebssystem kann Stacks wachsen lassen, abhängig vom Betriebssystem. Hier ist also die allgemeine Regel: Platzieren Sie keine riesigen Arrays auf dem Stack.

  • Ist es außerhalb einer Funktion, dann ist es global (Prozessspeicher), wenn das Betriebssystem nicht so viel Speicher zuweisen kann, wenn es versucht, Ihr Programm zu laden, stürzt Ihr Programm ab und Ihr Programm hat keine Chance, dies zu bemerken (also das Folgende besser:)

  • Große Arrays sollten sein malloc‘ed. Mit malloc gibt das Betriebssystem einen Nullzeiger zurück, wenn die malloc fehlgeschlagen ist, schlägt dies je nach Betriebssystem und seinem Paging-Schema und Speicherzuordnungsschema entweder fehl, wenn 1) es keinen kontinuierlichen Bereich mit freiem Speicher gibt, der groß genug für das Array ist, oder 2) das Betriebssystem nicht genügend Bereiche mit freiem physischen Speicher abbilden kann in einen Speicher, der Ihrem Prozess als kontinuierlicher Speicher erscheint.

Also, mit großen Arrays tun Sie dies:

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

Benutzer-Avatar
Johannes Bode

Das Deklarieren beliebig großer Arrays, um Pufferüberläufe zu vermeiden, ist eine schlechte Praxis. Wenn Sie im Voraus wirklich nicht wissen, wie groß ein Puffer sein muss, verwenden Sie malloc oder realloc um den Puffer nach Bedarf dynamisch zuzuweisen und zu erweitern, möglicherweise unter Verwendung eines kleineren Puffers mit fester Größe als Vermittler.

Beispiel:

#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");

       }
     }
   }

Benutzer-Avatar
Jon

Wenn das Array auf dem Stapel zugewiesen werden soll, sind Sie durch die Stapelgröße (normalerweise 1 MB unter Windows, ein Teil davon wird verwendet, sodass Sie noch weniger haben). Ansonsten stelle ich mir das Limit ziemlich groß vor.

Jedoch, Das Array wirklich groß zu machen, ist keine Lösung für Pufferüberlaufprobleme. Tu es nicht. Verwenden Sie Funktionen, die über einen Mechanismus zur Begrenzung der verwendeten Puffermenge verfügen, um sicherzustellen, dass Sie Ihren Puffer nicht überschreiten, und machen Sie die Größe angemessener (z. B. 1 KB).

Sie können verwenden malloc() um größere Teile des Speichers zu erhalten, als ein Array normalerweise verarbeiten könnte.

Benutzer-Avatar
Jon Hanna

Nun, ein Pufferüberlauf würde nicht durch einen zu großen Wert für HUGE_NUMBER verursacht werden, sondern vielmehr durch einen zu kleinen Wert im Vergleich zu dem, was darin geschrieben wurde (schreiben Sie in den Index HUGE_NUMBER oder höher, und Sie haben den Puffer überlaufen lassen).

Abgesehen davon hängt es von der Maschine ab. Es gibt sicherlich Systeme, die mehrere Millionen auf dem Haufen und ungefähr eine Million auf dem Stapel (abhängig von anderen Drücken) verarbeiten könnten, aber es gibt sicherlich auch einige, die nicht mehr als ein paar Hundert verarbeiten könnten (kleine eingebettete Geräte wären es ein offensichtliches Beispiel). Während 65.535 ein vom Standard vorgegebenes Minimum ist, könnte ein wirklich kleines Gerät angeben, dass der Standard aus diesem Grund bewusst verlassen wurde.

In Wirklichkeit belasten Sie den Speicher auf einer großen Maschine unnötigerweise auf eine Weise, die die Leistung beeinträchtigt, lange bevor Ihnen tatsächlich der Speicher ausgeht. Es wäre besser, ein Array dynamisch auf eine geeignete Größe zu dimensionieren.

1298790cookie-checkWie viele Zeichen können in einem Char-Array enthalten sein?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy