Ich würde gerne wissen, was der Unterschied zwischen statischer Speicherzuweisung und dynamischer Speicherzuweisung ist.
Können Sie das an einem Beispiel erläutern?
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?
Brice
Dies ist eine Standard-Interviewfrage:
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.
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)
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 */
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.
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 🙂
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
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
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.
Wein
Statische Speicherzuweisung:
Dynamische Speicherzuweisung:
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
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
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