Statisches Array vs. dynamisches Array in C ++


88

Was ist der Unterschied zwischen einem statischen Array und einem dynamischen Array in C ++?

Ich muss eine Aufgabe für meine Klasse machen und es heißt, keine statischen Arrays zu verwenden, sondern nur dynamische Arrays. Ich habe im Buch und online nachgesehen, aber ich scheine es nicht zu verstehen.

Ich dachte, dass statisch zur Kompilierungszeit und dynamisch zur Laufzeit erstellt wurde, aber ich könnte dies mit der Speicherzuweisung verwechseln.

Können Sie den Unterschied zwischen statischem und dynamischem Array in C ++ erklären?


1
Statisch ist nicht das Gegenteil von Dynamik. Entweder ist das Buch, das Sie verwenden, schrecklich, oder Sie nehmen es aus dem Zusammenhang. Ich werde unten eine neue Antwort hinzufügen, um dies hoffentlich zu klären.
Joshua Clayton

3
Siehe das Diagramm in dieser Frage: stackoverflow.com/a/11698458/1143274 Statische Arrays sind weder auf dem Stapel noch auf dem Heap zugeordnet.
Evgeni Sergeev

* festes Array gegen dynamisches Array
csguy

Antworten:


101

Lokale Arrays werden auf dem Stapel erstellt und haben eine automatische Speicherdauer. Sie müssen den Speicher nicht manuell verwalten, sie werden jedoch zerstört, wenn die Funktion, in der sie sich befinden, beendet wird. Sie haben notwendigerweise eine feste Größe:

int foo[10];

Mit erstellte Arrays operator new[]haben eine dynamische Speicherdauer und werden auf dem Heap gespeichert (technisch gesehen der "freie Speicher"). Sie können jede Größe haben, aber Sie müssen sie selbst zuweisen und freigeben, da sie nicht Teil des Stapelrahmens sind:

int* foo = new int[10];
delete[] foo;

17
Dies ist richtig, aber nur um zu veranschaulichen, wie es funktioniert. Bitte tun Sie dies nicht in echtem Code, sondern verwenden Sie stattdessen einen std :: vector.
Eddy Pronk

22
@ Eddie: Es hängt von der Situation ab, ob ein Vektor notwendig ist
Casebash

6
@Casebash: In welcher Situation würden Sie ein Array bevorzugen? "Sie sollten immer lieber Vektoren oder Deques anstelle von Arrays verwenden." - Herb Sutter (außergewöhnlicher C ++)
Eddy Pronk

15
@EddyPronk Aus Gründen der Speicherfragmentierung kann ein festes Array als eine Art Pool verwendet werden. Nicht jeder Fall erfordert den Heap, die Verwendung von stapelbasierten Arrays bietet besondere Vorteile. Sie behandeln den std :: vector als goldenen Hammer, ein gängiges Anti-Pattern.
void.pointer

4
@EddyPronk: Ich bin mir ziemlich sicher, dass Herb Sutter dynamische Arrays meinte, wie int* foo = new int[N]Sie sie für sich deleteselbst haben und daher bei Ausnahmen vorsichtig sein müssen. Statische Arrays haben diese Probleme nicht.
Alexander Malakhov

31

static ist ein Schlüsselwort in C und C ++. Daher hat static anstelle eines allgemeinen beschreibenden Begriffs eine sehr spezifische Bedeutung, wenn es auf eine Variable oder ein Array angewendet wird. Um die Verwirrung zu verstärken, hat es drei verschiedene Bedeutungen in getrennten Kontexten. Aus diesem Grund kann ein statisches Array entweder fest oder dynamisch sein.

Lassen Sie mich erklären:

Das erste ist C ++ spezifisch:

  • Ein statisches Klassenmitglied ist ein Wert, der nicht mit dem Konstruktor instanziiert oder mit dem Destruktor gelöscht wird. Dies bedeutet, dass das Mitglied auf andere Weise initialisiert und verwaltet werden muss. statisches Element können Zeiger sein, die auf null initialisiert und dann beim ersten Aufruf eines Konstruktors zugewiesen werden. (Ja, das wäre statisch und dynamisch)

Zwei werden von C geerbt:

  • Innerhalb einer Funktion ist eine statische Variable eine Variable, deren Speicherort zwischen Funktionsaufrufen erhalten bleibt. Es ist insofern statisch, als es nur einmal initialisiert wird und seinen Wert zwischen Funktionsaufrufen beibehält (die Verwendung von Statik macht eine Funktion nicht wiedereintrittsfähig, dh nicht threadsicher).

  • Außerhalb von Funktionen deklarierte statische Variablen sind globale Variablen, auf die nur innerhalb desselben Moduls zugegriffen werden kann (Quellcodedatei mit anderen # Includes).

Die Frage (glaube ich), die Sie stellen wollten, ist, was der Unterschied zwischen dynamischen Arrays und Arrays mit fester oder Kompilierungszeit ist. Dies ist eine einfachere Frage. Arrays zur Kompilierungszeit werden im Voraus festgelegt (wenn das Programm kompiliert wird) und sind Teil eines Funktionsstapelrahmens. Sie werden zugewiesen, bevor die Hauptfunktion ausgeführt wird. Dynamische Arrays werden zur Laufzeit mit dem Schlüsselwort "new" (oder der Malloc-Familie aus C) zugewiesen, und ihre Größe ist nicht im Voraus bekannt. Dynamische Zuordnungen werden nicht automatisch bereinigt, bis das Programm nicht mehr ausgeführt wird.


4
+1, Ihre Antwort ist die genaueste und präziseste und hätte mehr Stimmen erhalten sollen.
Z Boson

Wenn Sie die Größe des Arrays mit dem new[]Operator deklarieren , wie kommt es dann, dass die Größe erst zur Laufzeit bekannt ist? dhint* p = new int[10]
wulfgarpro

"Sie werden zugewiesen, bevor die Hauptfunktion ausgeführt wird." Warum die Stapelvariablen zuordnen, bevor der entsprechende Block eingegeben wird?
AlwaysLearning

Stapelvariablen (im Allgemeinen lokale Variablen in einer Funktion) haben eine vordefinierte Größe und Position innerhalb eines Stapelrahmens, und der gesamte Stapel wird zugewiesen, bevor die Hauptfunktion @AlwaysLearning ausgeführt wird. Bei der Eingabe eines Stapelrahmens über einen Funktionsaufruf wird der Stapelzeiger aktualisiert, der neue Stapelrahmen befindet sich jedoch innerhalb des Stapels. Es wird nie mehr ein Stapel zugewiesen. Tatsächlich führen zu große Variablen (z. B. ein riesiges Array) oder zu viele gleichzeitig geöffnete Funktionsaufrufe zu einem Stapelüberlauf, nach dem diese Site benannt ist.
Joshua Clayton

@ JoshuaClayton Ich denke, das kann nicht richtig sein. Wie können Sie die Stapelrahmen (beachten Sie den Plural) für eine rekursive Funktion zuweisen, wenn Sie nicht wissen, wie oft sie eingegeben werden?
AlwaysLearning

11

Ich denke, die Semantik, die in Ihrer Klasse verwendet wird, ist verwirrend. Was wahrscheinlich mit "statisch" gemeint ist, ist einfach "konstante Größe", und was wahrscheinlich mit "dynamisch" gemeint ist, ist "variable Größe". In diesem Fall könnte ein Array mit konstanter Größe folgendermaßen aussehen:

int x[10];

und eine "dynamische" wäre einfach jede Art von Struktur, die es ermöglicht, den zugrunde liegenden Speicher zur Laufzeit zu vergrößern oder zu verkleinern. Meistens reicht die std::vectorKlasse aus der C ++ - Standardbibliothek aus. Verwenden Sie es so:

std::vector<int> x(10); // this starts with 10 elements, but the vector can be resized.

std::vectorhat operator[]definiert, so dass Sie es mit der gleichen Semantik wie ein Array verwenden können.


1
Ich denke, es ist ziemlich klar, dass mit "dynamischem Array" einfach ein dynamisch zugewiesenes Array gemeint ist (dh eines, in dem die Größe zur Laufzeit dynamisch angegeben werden kann). Likenew int[10]
Jalf

@jalf: Ich war mehr besorgt über den Begriff "statisch". Aus Gründen der Konsistenz ziehe ich es vor, ein "dynamisches Array" als Array mit zugeordneter oder variabler Größe zu bezeichnen.
Ben Collins

Guter Punkt, da ein statisches Array automatisch und auf dem Stapel implementiert oder global und in einem Datenabschnitt implementiert sein kann. Beide sind statisch, aber intern kann der Code, der auf sie zugreift, sehr unterschiedlich sein.
Z Boson

9

Statischen Arrays wird zur Kompilierungszeit Speicher zugewiesen, und der Speicher wird auf dem Stapel zugewiesen. Während den dynamischen Arrays zur Laufzeit Speicher zugewiesen wird und der Speicher vom Heap zugewiesen wird.

int arr[] = { 1, 3, 4 }; // static integer array.   
int* arr = new int[3]; // dynamic integer array.

4
Ein globales Array ist ein statisches Array und wird in einem Datenabschnitt und nicht vom Stapel implementiert.
Z Boson

8

Es ist wichtig, klare Definitionen der Begriffe zu haben. Leider scheint es mehrere Definitionen dafür zu geben, was statische und dynamische Arrays bedeuten.

Statische Variablen sind Variablen, die mithilfe der statischen Speicherzuordnung definiert werden . Dies ist ein allgemeines Konzept, das von C / C ++ unabhängig ist. In C / C ++ können wir statische Variablen mit globalem, Datei- oder lokalem Bereich wie folgt erstellen:

int x[10]; //static array with global scope
static int y[10]; //static array with file scope
foo() {
    static int z[10]; //static array with local scope

Automatische Variablen werden normalerweise mithilfe einer stapelbasierten Speicherzuordnung implementiert . Ein automatisches Array kann in C / C ++ folgendermaßen erstellt werden:

foo() {
    int w[10]; //automatic array

Was diese Arrays x, y, z, undw gemeinsam haben , ist , dass die Größe für jeden von ihnen befestigt ist und während der Kompilierung definiert.

Einer der Gründe, warum es wichtig ist, die Unterscheidung zwischen einem automatischen Array und einem statischen Array zu verstehen, besteht darin, dass statischer Speicher normalerweise im Datenabschnitt (oder BSS-Abschnitt ) einer Objektdatei implementiert ist und der Compiler absolute Adressen verwenden kann, um auf die Arrays zuzugreifen Dies ist mit stapelbasiertem Speicher nicht möglich.

Was normalerweise mit einem dynamischen Array gemeint ist, ist nicht eines, dessen Größe geändert werden kann, sondern eines, das mithilfe einer dynamischen Speicherzuordnung mit einer zur Laufzeit festgelegten festen Größe implementiert wird. In C ++ erfolgt dies mit dem newOperator .

foo() {
   int *d = new int[n]; //dynamically allocated array with size n     

Es ist jedoch möglich, ein automatisches Array mit einer zur Laufzeit definierten Fixgröße zu erstellen, indem alloca:

foo() {
    int *s = (int*)alloca(n*sizeof(int))

Für ein echtes dynamisches Array sollte man so etwas wie std::vectorin C ++ verwenden (oder ein Array mit variabler Länge in C ).

Was war für die Aufgabe in der Frage des OP gedacht? Ich denke, es ist klar, dass nicht ein statisches oder automatisches Array gewünscht wurde, sondern eines, das entweder die dynamische Speicherzuweisung mit dem newOperator oder ein Array mit nicht fester Größe unter Verwendung von z std::vector.


3

Ich denke in diesem Zusammenhang bedeutet dies, dass es in dem Sinne statisch ist, dass die Größe fest ist. Verwenden Sie std :: vector. Es hat eine resize () Funktion.


2

Sie könnten ein pseudo-dynamisches Array haben, bei dem die Größe vom Benutzer zur Laufzeit festgelegt wird, danach jedoch festgelegt wird.

int size;
cin >> size;
int dynamicArray[size];

Nicht Teil von Standard C ++ (in C99 und als Compiler-Erweiterung für gcc).
Crashmstr

0

Ja, richtig, das statische Array wird zur Kompilierungszeit erstellt, während das dynamische Array zur Laufzeit erstellt wird. Wenn der Unterschied in Bezug auf ihre Speicherorte besteht, befinden sich die statischen Daten auf dem Stapel und die dynamischen werden auf dem Heap erstellt. Alles, was sich auf dem Heap befindet, benötigt die Speicherverwaltung, bis ein Garbage Collector wie im Fall des .net-Frameworks vorhanden ist, da sonst die Gefahr eines Speicherverlusts besteht.


0

Statisches Array: Effizienz. Es ist keine dynamische Zuordnung oder Freigabe erforderlich.

In C, C ++ deklarierte Arrays mit statischem Modifikator sind statisch. Beispiel: static int foo [5];


1
@admdrew, das stimmt, aber die Frage wurde nie gut beantwortet. Die beste Antwort ist Joshua Claytons Antwort, aber ich denke, eine bessere Antwort ist diese eine stackoverflow.com/questions/17775066/…
Z Boson

@ Zboson Gut zu wissen, danke. Heh und ich haben gerade gemerkt, dass ich diesen Kommentar vor fast einem Jahr gemacht habe.
Admdrew

-3

statische arrary meens mit dem Angeben von Elementen in der Seite des Arrays

Dynamische Arrary-Meens, ohne Elemente in der Seite des Arrays anzugeben

Beispiel:

     char a[10]; //static array
       char a[];  //dynamic array

Ich denke, er hat richtig gesagt. Wenn Sie eine genaue Länge für das Array angeben, handelt es sich um ein statisches Array, und wenn Sie keine Länge angeben, handelt es sich um ein dynamisches Array. Aber da er nicht weiß, wie man Englisch schreibt, notieren die Leute diese Antwort.
Muhammad Tayyab
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.