Das beunruhigt mich schon eine Weile. Es geht um mein (mangelndes) Verständnis des Unterschieds zwischen statischer und dynamischer Speicherzuweisung. Das folgende Array ist ein normales statisches Array, das bedeutet, dass der Speicher während der Kompilierungszeit zugewiesen wird, richtig? Aber ich habe es so eingerichtet, dass der Benutzer die Array-Größe zur Laufzeit eingibt.
%Vor% Beachten Sie, dass in diesem Programm keine Operatoren new
oder delete
vorhanden sind. Es funktioniert gut in Xcode 4.2 (Standard-Clang-Compiler) sowie auf dem UNIX-Server meiner Schule (GCC 4.4.5). Wie weiß der Compiler, wie viel Speicher für arr
reserviert werden muss, wenn das Array zur Kompilierzeit erstellt wird? Ist das nur ein Zufall meines Compilers, gefährlicher Code, der anderen Speicher korrumpieren könnte, oder ist das echt?
Dies ist eine nicht standardmäßige Erweiterung Ihrer C ++ - Compiler. Beachten Sie, dass in C im Gegensatz zu C ++ dies seit C99 offiziell unterstützt wird (d. H. Standardmandatiertes Verhalten). In C ++ wird es nicht unterstützt, da es bereits eine Lösung für das Problem gibt: Verwenden Sie std::vector
anstelle des Arrays.
Nicht jedoch, dass das Array nicht ist, das die statische Speicherzuweisung verwendet (auch nicht die dynamische Speicherzuweisung), sondern die automatische Speicherzuweisung. Automatische Variablen werden automatisch am Ende der Funktion freigegeben (der Speicherbereich, in dem sie zugewiesen sind, wird als Stapel bezeichnet, da die Zuweisungen und Deallokationen darauf Stapelsemantik haben). Damit das Array die statische Speicherzuweisung verwendet, müssen Sie static
vor die Definition setzen (Beachten Sie, dass Variablen im globalen oder Namespace-Bereich immer die statische Speicherzuweisung verwenden). Wenn Sie jedoch die Variable statisch machen, werden Sie feststellen, dass der Compiler keine nicht konstante Array-Größe mehr zulässt.
Beachten Sie, dass std::vector
stattdessen seine Daten mit dynamischen Speicherzuweisungen speichert. Aus diesem Grund können Sie auch für statische std::vector
s eine nicht konstante Größe verwenden.
Für ein Array (oder ein beliebiges Objekt), das innerhalb einer Funktion deklariert ist, wird der Speicher beim Eintritt in die Funktion (normalerweise auf dem Stapel) zugewiesen und bei Zuweisung der Funktion wieder freigegeben. Die Tatsache, dass die Funktion in diesem Fall main
ist, hat keinen Einfluss darauf.
Dies:
%Vor%ist ein "Array variabler Länge" (VLA). Die Sache ist, C ++ unterstützt keine VLAs. C tut dies, beginnend mit dem ISO-C-Standard von 1999 (C99), aber es ist kein Merkmal, das C ++ übernommen hat.
Ihr Compiler unterstützt VLAs in C ++ als Erweiterung. Wenn Sie sie verwenden, ist Ihr Code nicht tragbar.
(Ein Problem mit VLAs ist, dass es keinen Mechanismus gibt, um einen Zuweisungsfehler zu erkennen; wenn arraySize
zu groß ist, ist das Programmverhalten nicht definiert).
Für gcc erzeugt das Kompilieren mit -pedantic
eine Warnung:
Der generierte Code weist Array-Size-Bytes zur Laufzeit auf dem Stack zu. Sobald die Funktion zurückkehrt, wird der Stapel abgewickelt, einschließlich "Zurückgeben" der Bytes, die ihm für das Array zugewiesen wurden.
Mit new und delete wird Speicherplatz auf dem Heap zugewiesen. Die zugewiesene Speicherlebensdauer auf dem Heap ist unabhängig von einem Funktions- oder Methodenbereich. Wenn Sie ihm in einer Funktion Speicherplatz zuweisen und die Funktion zurückgibt, ist der Speicher weiterhin zugewiesen und gültig.
Es ist ein Array variabler Länge (nur in C99 und nicht in C ++ unterstützt). Es wird zur Laufzeit auf dem Stack zugeordnet.
Tags und Links arrays c++ dynamic-memory-allocation dynamic-arrays