it-swarm.com.de

Unterschied zwischen statischer Speicherzuordnung und dynamischer Speicherzuordnung

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

Könnten Sie das mit einem Beispiel erklären?

67
Nishant Kumar

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

Static Allocation bedeutet, dass der Speicher für Ihre Variablen beim Programmstart zugewiesen wird. Die Größe wird festgelegt, wenn das Programm erstellt wird. Sie gilt für globale Variablen, Variablen für den Dateibereich und für Variablen, die mit static qualifiziert sind, das in Funktionen definiert ist.

Automatische Speicherzuordnung tritt für (nicht statische) Variablen auf, die in Funktionen definiert sind, und wird normalerweise auf stack gespeichert (obwohl der C-Standard nicht die Verwendung eines Stacks vorschreibt). Sie müssen keinen zusätzlichen Speicher reservieren, haben aber auch eine begrenzte Kontrolle über die Lebensdauer dieses Speichers. Zum Beispiel: Automatische Variablen in einer Funktion sind nur solange vorhanden, bis die Funktion beendet ist.

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

Dynamische Speicherzuordnung ist etwas anders. Sie steuern jetzt die genaue Größe und die Lebensdauer dieser Speicherorte. Wenn Sie es nicht freigeben, stoßen Sie auf Speicherverluste, die zum Absturz der Anwendung führen können, da das System zu einem bestimmten Zeitpunkt keinen Speicher mehr zuweisen kann.

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

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

Im oberen Beispiel ist der zugewiesene Speicher 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);
68
Constantinius

Dies ist eine Standard-Interviewfrage:

Dynamische Speicherzuordnung

Ist der Speicher zur Laufzeit mit calloc(), malloc() und Freunden belegt. Es wird manchmal auch als "Heap-Speicher" bezeichnet, obwohl es nichts mit der Heap-Datenstruktur ref .

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

Der Heapspeicher bleibt solange erhalten, bis free() aufgerufen wird. Mit anderen Worten, Sie steuern die Lebensdauer der Variablen.

Automatische Speicherzuordnung

Dies ist, was allgemein als "Stapelspeicher" bezeichnet wird, und wird zugewiesen, wenn Sie einen neuen Bereich eingeben (normalerweise, wenn eine neue Funktion in den Aufrufstapel gepusht wird). Wenn Sie den Bereich verlassen, sind die Werte der automatischen Speicheradressen undefiniert, und es ist ein Fehler beim Zugriff auf diese Adressen

int a = 43;

Beachten Sie, dass der Gültigkeitsbereich nicht unbedingt die Funktion bedeutet. Bereiche können sich innerhalb einer Funktion verschachteln, und die Variable ist nur innerhalb des Blocks, in dem sie deklariert wurde. Beachten Sie auch, dass nicht angegeben ist, wo dieser Speicher zugewiesen ist. (Auf einem sane -System befindet es sich auf dem Stack oder wird zur Optimierung registriert)

Statische Speicherzuordnung

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

In C kann statischer Speicher mit dem Schlüsselwort static zugewiesen werden. Der Geltungsbereich ist nur die Übersetzungseinheit. 

Dinge werden interessanter wenn das Schlüsselwort extern betrachtet wird . Wenn eine Variable externdefined ist, ordnet der Compiler Speicher zu. Wenn eine Variable externdeklariert ist, verlangt der Compiler, dass die Variable an anderer Stelle defined ist. Fehler beim Deklarieren/Definieren von extern-Variablen führen zu Verknüpfungsproblemen, während Fehler beim Deklarieren/Definieren von static-Variablen zu Kompilierungsproblemen führen.

im Dateibereich ist das statische Schlüsselwort optional (außerhalb einer Funktion):

int a = 32;

Aber nicht im Funktionsumfang (innerhalb einer Funktion):

static int a = 32;

Technisch gesehen sind extern und static zwei verschiedene Klassen von Variablen in C.

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

Speicher registrieren

Die letzte Speicherklasse sind 'Registervariablen'. Wie erwartet, sollten Registervariablen im Register einer CPU zugewiesen werden, die Entscheidung bleibt jedoch dem Compiler überlassen. Sie können eine Registervariable nicht in eine Referenz umwandeln, indem Sie Adresse von verwenden. 

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

Die meisten modernen Compiler sind intelligenter als Sie, wenn Sie auswählen, welche Variablen in Register eingetragen werden sollen :)

Verweise:

Hinweise zur statischen Speicherzuordnung

Es ist etwas verwirrend zu sagen, dass statischer Speicher während des Kompilierens zugewiesen wird, insbesondere wenn man bedenkt, dass der Kompilierungscomputer und der Hostcomputer möglicherweise nicht identisch sind oder sich nicht in derselben Architektur befinden. 

Es kann besser sein, zu denken, dass die Zuweisung von statischem Speicher vom Compiler und nicht von zur Kompilierzeit verwaltet wird. Zum Beispiel kann der Compiler einen großen data-Abschnitt in der kompilierten Binärdatei erstellen. Wenn das Programm in den Speicher geladen wird, wird die Adresse im data-Segment des Programms als Speicherort 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, Binärdateien mit mehreren Gigabyte zu schreiben, die aus weniger als einem halben Dutzend Codezeilen generiert werden. Eine andere Option besteht darin, dass der Compiler Initialisierungscode einfügt, der Speicher auf andere Weise reserviert, 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 wird. Sie können dies selbst ausprobieren, indem Sie ein kleines C-Programm schreiben, das ein großes statisches Array mit 10k, 1m, 10m, 100m, 1G oder 10G-Elementen zuordnet. Bei vielen Compilern wächst die binäre Größe linear mit der Größe des Arrays und wird ab einem bestimmten Punkt wieder kleiner, da der Compiler eine andere Zuordnungsstrategie verwendet.

92
brice

Dynamische Speicherzuordnung - Speicher wird zur Laufzeit im Heap zugewiesen. Dies wird verwendet, wenn die Menge (Größe) des Speichers variabel ist und nur zur Laufzeit bekannt ist. Die dynamische Zuordnung wird durch bestimmte Funktionen wie malloc (), calloc (), realloc (), free in C und "new", "delete" in C++ erreicht.

Static Memory Allocation - Speicher, der zur Kompilierzeit in Stack oder anderen Datensegmenten zugewiesen wird. Dies wird verwendet, wenn die Menge (Größe) des Speichers statisch/konstant ist und während der Kompilierzeit bekannt ist.

3
vinay

Statische Speicherzuordnung: Der Compiler ordnet den erforderlichen Speicherplatz für eine deklarierte Variable zu. Durch Verwendung der Adresse des Operators wird die reservierte Adresse abgerufen, und diese Adresse kann einer Zeigervariable zugewiesen werden statischer Speicher, diese Art der Zuweisung eines Zeigerwerts zu einer Zeigervariable wird als statische Speicherzuordnung bezeichnet. Speicher wird während der Übersetzungszeit zugewiesen.

Dynamische Speicherzuordnung: 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, sind solche Zuweisungen bekannt als dynamische Speicherzuweisung. Der Speicher wird zur Laufzeit geprüft.

2
Rajeev Kumar

Unterschied zwischen STATIC MEMORY ALLOCATION & DYNAMISCHE MEMORY ALLOCATION  

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

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

Variablen bleiben fest zugeordnet.
Wird nur zugewiesen, wenn die Programmeinheit aktiv ist. 

Implementiert mit Stacks und Heaps.
Wird mit Datensegmenten implementiert. 

Zeiger wird benötigt, um auf Variablen zuzugreifen.
Kein Bedarf an dynamisch zugewiesenen Zeigern. 

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

Mehr Speicherplatz erforderlich.
Weniger Speicherplatz erforderlich. 

1
Ebenezer

Der statischen Speicherzuordnung wird Speicher zugewiesen, bevor das Programm während der Kompilierzeit ausgeführt wird . Dynamische Speicherzuweisung wird während der Ausführung des Programms zur Laufzeit Speicher zugewiesen.

0
Ritu maheswari

Statische Speicherzuordnung Der zugewiesene Speicher liegt im Stapel.

int a[10];

Dynamische Speicherzuordnung Der zugewiesene Speicher befindet sich im Heap.

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

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

free(a);
0
onemach