Unterschied zwischen statischer Speicherzuweisung und dynamischer Speicherzuweisung

Lesezeit: 9 Minuten

Benutzeravatar von Nishant Kumar
Nishant Kumar

Ich würde gerne wissen, was der Unterschied zwischen statischer Speicherzuweisung und dynamischer Speicherzuweisung ist.

Können Sie das an einem Beispiel erläutern?

Benutzeravatar von brice
Brice

Dies ist eine Standard-Interviewfrage:

Dynamische Speicherzuweisung

Wird Speicher zur Laufzeit zugewiesen mit calloc(), malloc() und Freunde. Er wird manchmal auch als „Heap“-Speicher bezeichnet, obwohl er nichts mit der Heap-Datenstruktur zu tun hat Ref.

int * a = malloc(sizeof(int));

Heap-Speicher ist persistent bis free() wird genannt. Mit anderen Worten, Sie steuern die Lebensdauer der Variablen.

Automatische Speicherzuweisung

Dies ist allgemein als „Stack“-Speicher bekannt und wird zugewiesen, wenn Sie einen neuen Bereich eingeben (normalerweise, wenn eine neue Funktion auf den Aufrufstapel übertragen wird). Sobald Sie den Gültigkeitsbereich verlassen, sind die Werte der automatischen Speicheradressen undefiniert, und es ist ein Fehler, auf sie zuzugreifen.

int a = 43;

Beachten Sie, dass Umfang nicht unbedingt Funktion bedeutet. Geltungsbereiche können innerhalb einer Funktion verschachtelt werden, und die Variable befindet sich nur innerhalb des Blocks, in dem sie deklariert wurde, innerhalb des Geltungsbereichs. Beachten Sie auch, dass nicht angegeben ist, wo dieser Speicher zugewiesen wird. (Auf einen vernünftig System wird es auf dem Stack sein oder sich zur Optimierung registrieren)

Statische Speicherzuweisung

Wird zur Kompilierzeit zugewiesen*und die Lebensdauer einer Variablen im statischen Speicher ist die Lebensdauer des Programms.

In C kann statischer Speicher mithilfe von zugewiesen werden static Stichwort. Der Geltungsbereich ist nur die Übersetzungseinheit.

Die Dinge werden interessanter wenn der extern Stichwort berücksichtigt. Wenn ein extern variabel ist definiert der Compiler weist Speicher dafür zu. Wenn ein extern variabel ist erklärterfordert der Compiler, dass die Variable ist definiert anderswo. Fehler bei der Deklaration/Definition extern Variablen verursachen Verknüpfungsprobleme, während sie nicht deklariert/definiert werden können static Variablen führen zu Kompilierungsproblemen.

Im Dateibereich ist das Schlüsselwort static optional (außerhalb einer Funktion):

int a = 32;

Aber nicht im Funktionsumfang (innerhalb einer Funktion):

static int a = 32;

Technisch, extern und static sind zwei getrennte Klassen von Variablen in C.

extern int a; /* Declaration */
int a; /* Definition */

*Hinweise zur statischen Speicherallokation

Es ist etwas verwirrend zu sagen, dass statischer Speicher zur Kompilierzeit zugewiesen wird, insbesondere wenn wir in Betracht ziehen, dass die Kompilierungsmaschine und die Hostmaschine möglicherweise nicht gleich sind oder nicht einmal auf derselben Architektur.

Vielleicht ist es besser, nachzudenken dass die Zuweisung des statischen Speichers vom Compiler übernommen wird statt zur Kompilierzeit zugewiesen.

Beispielsweise kann der Compiler eine große data Abschnitt in der kompilierten Binärdatei und wenn das Programm in den Speicher geladen wird, die Adresse innerhalb der data Segment des Programms wird als Ort des zugewiesenen Speichers verwendet. Dies hat den deutlichen Nachteil, dass die kompilierte Binärdatei sehr groß wird, wenn viel statischer Speicher verwendet wird. Es ist möglich, eine Multi-Gigabyte-Binärdatei zu schreiben, die aus weniger als einem halben Dutzend Codezeilen generiert wird. Eine andere Möglichkeit besteht darin, dass der Compiler Initialisierungscode einfügt, der Speicher auf andere Weise zuweist, bevor das Programm ausgeführt wird. Dieser Code variiert je nach Zielplattform und Betriebssystem. In der Praxis verwenden moderne Compiler Heuristiken, um zu entscheiden, welche dieser Optionen verwendet werden sollen. Sie können dies selbst ausprobieren, indem Sie ein kleines C-Programm schreiben, das ein großes statisches Array von entweder 10k-, 1m-, 10m-, 100m-, 1G- oder 10G-Elementen zuweist. Bei vielen Compilern wächst die Binärgröße linear mit der Größe des Arrays und schrumpft ab einem bestimmten Punkt wieder, wenn der Compiler eine andere Zuweisungsstrategie verwendet.

Speicher registrieren

Die letzte Speicherklasse sind ‘Register’-Variablen. Wie erwartet sollten Registervariablen einem CPU-Register zugewiesen werden, aber die Entscheidung wird tatsächlich dem Compiler überlassen. Sie dürfen eine Registervariable nicht mit address-of in eine Referenz umwandeln.

register int meaning = 42;
printf("%p\n",&meaning); /* this is wrong and will fail at compile time. */

Die meisten modernen Compiler sind klüger als Sie bei der Auswahl der Variablen, die in Registern abgelegt werden sollen 🙂

Verweise:

  • Hinweis: Ich würde vorschlagen int * a = malloc(sizeof(*a)); stattdessen, um eine Wiederholung des Typs von zu vermeiden a. Dies macht die Dinge viel einfacher, wenn überhaupt die Art von a Änderungen.

    – Shahbaz

    3. April 2013 um 16:56 Uhr

  • Eigentlich heißt es Heap, hat aber nichts mit Heap-Datenstruktur zu tun. Haufen bedeutet in diesem Fall einen unordentlichen Ort

    – dynamisch

    2. November 2014 um 12:23 Uhr

  • “Statische Speicherzuweisung … wird zur Kompilierzeit zugewiesen” Meinen Sie die Zuweisungsgröße? bestimmt zur Kompilierzeit? Würde die Speicherreservierung nicht nur zur Laufzeit erfolgen?

    – lf215

    27. Juli 2017 um 5:47 Uhr

  • Hey, ich habe Zweifel, wenn Sie immer noch antworten 🙁 . Was ist mit der automatischen Speicherzuweisung? Wird der Compiler auch Adressen im Datenabschnitt für diese lokalen Variablen speichern und an die ausführbare Datei weitergeben. Und wenn der Code ausgeführt wird (und in den Bereich eintritt ) werden diese Adressen tatsächlich als Orte des zugewiesenen Speichers verwendet.Oder wird es tatsächlich nur zur Laufzeit zugewiesen, ohne Adressgenerierung und -behandlung durch meinen Compiler?

    – LocalHost

    22. Oktober 2020 um 21:00 Uhr

  • @LocalHost Automatische Variablen sind auf die Lebensdauer des Kontexts (die geschweiften Klammern) beschränkt, in dem sie definiert wurden. das wird normalerweise zur Laufzeit auf dem Call-Stack zugewiesen. Es ist auf jeden Fall nicht im Datenbereich gespeichert. Sie können den C18-Standard hier lesen: (6.2.4.5-7) web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/…

    – Briese

    25. Oktober 2020 um 11:43 Uhr

Benutzeravatar von Constantinius
Konstantin

Es gibt drei Arten der Zuordnung: statisch, automatisch und dynamisch.

Statische Zuordnung bedeutet, dass der Speicher für Ihre Variablen beim Programmstart allokiert wird. Die Größe wird beim Erstellen des Programms festgelegt. Es gilt für globale Variablen, Dateibereichsvariablen und Variablen, die mit qualifiziert sind static definierte Innenfunktionen.

Automatische Speicherzuweisung tritt für (nicht statische) Variablen auf, die in Funktionen definiert sind, und wird normalerweise auf der gespeichert Stapel (obwohl der C-Standard nicht vorschreibt, dass ein Stack verwendet wird). Sie müssen damit keinen zusätzlichen Speicher reservieren, haben aber andererseits auch nur begrenzte Kontrolle über die Lebensdauer dieses Speichers. ZB: automatische Variablen in einer Funktion sind nur da, bis die Funktion beendet ist.

void func() {
    int i; /* `i` only exists during `func` */
}

Dynamische Speicherzuweisung ist etwas anders. Sie steuern nun die genaue Größe und die Lebensdauer dieser Speicherplätze. Wenn Sie ihn nicht freigeben, treten Speicherlecks auf, die zum Absturz Ihrer Anwendung führen können, da das System irgendwann keinen weiteren Speicher mehr zuweisen kann.

int* func() {
    int* mem = malloc(1024);
    return mem;
}

int* mem = func(); /* still accessible */

Im oberen Beispiel ist der zugewiesene Speicher immer noch gültig und zugänglich, obwohl die Funktion beendet wurde. Wenn Sie mit dem Speicher fertig sind, müssen Sie ihn freigeben:

free(mem);

  • Sicher, Sie haben die Kontrolle über die Lebensdauer der Variablen … Sie entscheiden über den Umfang, oder?

    – Luchian Grigore

    5. Dezember 2011 um 12:47 Uhr

  • -1 Diese Antwort ist falsch. Sie verwirren statisch und automatisch Variablen.

    – Briese

    3. April 2013 um 16:39 Uhr

  • Ihr eigener Satz lautet: „Statisch Allokation bedeutet, dass der Speicher für Ihre Variablen ist automatisch zugeordnet” Das ist falsch. Schauen Sie sich an, was die Handbuchseite für GNUs libc muss dazu was sagen.

    – Briese

    3. April 2013 um 21:18 Uhr


  • Die Stapelzuordnung ist nicht statisch. Es geschieht dynamisch zur Laufzeit und hängt eher von den Laufzeitbedingungen des Programms ab als von seinen statisch bekannten Eigenschaften (was was ist statisch bedeutet in C und Programmierung im Allgemeinen). Statische Zuordnung ist das, was die Compiler ableiten können, ohne das Programm tatsächlich auszuführen. Ich denke, du solltest deine Antwort umformulieren.

    – Eli Bendersky

    15. August 2016 um 12:56 Uhr


  • @EliBendersky Es wird jetzt umformuliert. Überprüfen Sie jetzt, ob es richtig ist.

    – Suraj Jain

    17. August 2016 um 10:31 Uhr

Benutzeravatar von Rajeev Kumar
Rajeev Kumar

Statische Speicherzuweisung: Der Compiler weist den erforderlichen Speicherplatz für eine deklarierte Variable zu. Durch Verwendung der Adresse des Operators wird die reservierte Adresse erhalten und diese Adresse kann einer Zeigervariablen zugewiesen werden. Da die meisten deklarierten Variablen statischen Speicher haben, ist diese Art der Zuweisung von Zeigern Wert zu einer Zeigervariablen wird als statische Speicherzuweisung bezeichnet. Speicher wird während der Kompilierzeit zugewiesen.

Dynamische Speicherzuweisung: Es verwendet Funktionen wie malloc( ) oder calloc( ), um Speicher dynamisch zu erhalten. Wenn diese Funktionen verwendet werden, um Speicher dynamisch zu erhalten, und die von diesen Funktionen zurückgegebenen Werte Zeigervariablen zugewiesen werden, werden solche Zuweisungen als dynamische Speicherzuweisung bezeichnet während der Laufzeit durchgeführt.

Benutzeravatar von vinay
Wein

Statische Speicherzuweisung:

  • Variablen werden zugewiesen permanent
  • Die Zuordnung erfolgt Vor Programmausführung
  • Es verwendet die aufgerufene Datenstruktur Stapel zum Implementieren einer statischen Zuordnung
  • Weniger effizient
  • Es gibt keine Wiederverwendbarkeit des Speichers

Dynamische Speicherzuweisung:

  • Variablen werden zugewiesen nur wenn das Teilprogramm aktiv wird
  • Die Zuordnung erfolgt während Programmausführung
  • Es verwendet die aufgerufene Datenstruktur Haufen zur Implementierung der dynamischen Zuordnung
  • Effizienter
  • Es gibt Wiederverwendbarkeit des Speichers . Speicher kann freigegeben werden, wenn er nicht benötigt wird

Benutzeravatar von Ebenezer
Ebenezer

Unterschied zwischen STATISCHE SPEICHERZUWEISUNG & DYNAMISCHE SPEICHERZUWEISUNG

Speicher wird zugewiesen, bevor die Ausführung des Programms beginnt (während der Kompilierung).
Speicher wird während der Ausführung des Programms zugewiesen.

Während der Ausführung werden keine Speicherzuweisungs- oder Freigabeaktionen durchgeführt.
Speicherbindungen werden während der Ausführung hergestellt und zerstört.

Variablen bleiben dauerhaft belegt.
Wird nur bei aktivem Teilprogramm belegt.

Implementiert mit Stacks und Heaps.
Implementiert mit Datensegmenten.

Pointer wird für den Zugriff auf Variablen benötigt.
Keine Notwendigkeit von dynamisch zugewiesenen Zeigern.

Schnellere Ausführung als Dynamic.
Langsamere Ausführung als statisch.

Mehr Speicherplatz erforderlich.
Weniger Speicherplatz erforderlich.

  • Die statische Speicherzuweisung wird auf Stack zugewiesen, während die dynamische Speicherzuweisung auf Heap zugewiesen wird

    – Usmanischer Kurde

    4. Januar 2013 um 8:16 Uhr


  • @UsmanKurd Das ist in Bezug auf statischen Speicher im Allgemeinen falsch. Siehe meine Antwort.

    – Briese

    27. August 2019 um 15:26 Uhr

Benutzeravatar von Ritu Maheswari
Ritu Maheswari

Die statische Speicherzuweisung wird vor der Ausführung des Programms während der Kompilierzeit Speicher zugewiesen. Dynamische Speicherzuweisung ist zugewiesener Speicher während der Ausführung des Programms zur Laufzeit.

  • Die statische Speicherzuweisung wird auf Stack zugewiesen, während die dynamische Speicherzuweisung auf Heap zugewiesen wird

    – Usmanischer Kurde

    4. Januar 2013 um 8:16 Uhr


  • @UsmanKurd Das ist in Bezug auf statischen Speicher im Allgemeinen falsch. Siehe meine Antwort.

    – Briese

    27. August 2019 um 15:26 Uhr

Benutzeravatar von Suraj Jain
Suraj Jain

Statische Speicherzuweisung. Der zugewiesene Speicher befindet sich im Stack.

int a[10];

Dynamische Speicherzuweisung. Der zugewiesene Speicher befindet sich im Heap.

int *a = malloc(sizeof(int) * 10);

und letzteres sollte sein freid da es in C keinen Garbage Collector (GC) gibt.

free(a);

  • Wie kann statischer Speicher auf dem Stack zugewiesen werden, wenn der Speicher auf dem Stack dynamisch ist? Variablen können jederzeit “abgeknallt” werden …

    – Abdel Alem

    24. August 2021 um 12:33 Uhr


1422220cookie-checkUnterschied zwischen statischer Speicherzuweisung und dynamischer Speicherzuweisung

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

Privacy policy