Zurück zu: C Tutorial
Der Vorgang der Speicherreservierung wird als Zuordnung bezeichnet. Die Art der Speicherzuweisung hängt vom Speichertyp ab.
C hat zwei Arten von Speicher: statischen Speicher und dynamischen Speicher.
Statischer Speicher
Statischer Speicher ist Speicher, der vor der Ausführung des Programms für Variablen reserviert wird. Die Zuordnung von statischem Speicher wird auch als Speicherzuweisung zur Kompilierungszeit bezeichnet.
C reserviert beim Kompilieren des Programms automatisch Speicher für jede Variable.
Wenn Sie beispielsweise ein Integer-Array mit 20 Studenten erstellen (z. B. für ein Sommersemester), reserviert C Speicherplatz für 20 Elemente, was normalerweise 80 Byte Speicher (20 * 4) entspricht:
Beispiel
int students[20];
printf("%lu", sizeof(students)); // 80 bytes
Doch wenn das Semester beginnt, stellt sich heraus, dass nur 12 Studierende teilnehmen. Dann haben Sie den Platz von 8 ungenutzten Elementen verschwendet.
Da Sie die Größe des Arrays nicht ändern können, bleibt Ihnen unnötig reservierter Speicher.
Beachten Sie, dass das Programm weiterhin ausgeführt wird und in keiner Weise beschädigt ist. Wenn Ihr Programm jedoch viel Code dieser Art enthält, kann es langsamer ausgeführt werden, als es optimal wäre.
Beachten Sie, dass das Programm weiterhin ausgeführt wird und in keiner Weise beschädigt ist. Wenn Ihr Programm jedoch viel Code dieser Art enthält, kann es langsamer ausgeführt werden, als es optimal wäre.
Dynamischer Speicher
Dynamischer Speicher ist Speicher, der nach dem Start des Programms zugewiesen wird. Die Zuweisung von dynamischem Speicher kann auch als Laufzeitspeicherzuweisung bezeichnet werden.
Anders als beim statischen Speicher haben Sie jederzeit die volle Kontrolle darüber, wie viel Speicher verwendet wird. Sie können Code schreiben, um zu bestimmen, wie viel Speicher Sie benötigen, und ihn zuordnen.
Der dynamische Speicher gehört nicht zu einer Variable, auf ihn kann nur über Zeiger zugegriffen werden.
Um dynamischen Speicher zuzuweisen, können Sie die Funktionen malloc()
oder calloc()
verwenden. Um sie verwenden zu können, muss der Header eingeschlossen werden. Die Funktionen malloc()
und calloc()
weisen Speicher zu und geben einen Zeiger auf seine Adresse zurück.
int *ptr1 = malloc(size);
int *ptr2 = calloc(amount, size);
Die Funktion malloc()
hat einen Parameter namens size, der angibt, wie viel Speicher in Bytes zugewiesen werden soll.
Die Funktion malloc()
hat einen Parameter namens size, der angibt, wie viel Speicher in Bytes zugewiesen werden soll.
- Menge – Gibt die Menge der zuzuweisenden Elemente an.
- Größe – Gibt die Größe jedes Elements in Bytes an.
Hinweis: Die Daten im von
malloc()
zugewiesenen Speicher sind unvorhersehbar. Um unerwartete Werte zu vermeiden, stellen Sie sicher, dass Sie etwas in den Speicher schreiben, bevor Sie ihn lesen.Im Gegensatz zu
malloc()
schreibt die Funktioncalloc()
Nullen in den gesamten zugewiesenen Speicher. Dies machtcalloc()
jedoch etwas weniger effizient.
Die beste Möglichkeit, einem Datentyp die richtige Speichermenge zuzuweisen, ist die Verwendung des sizeof
Operators:
int *ptr1, *ptr2;
ptr1 = malloc(sizeof(*ptr1));
ptr2 = calloc(1, sizeof(*ptr2));
Seien Sie vorsichtig,
sizeof(*ptr1)
weist C an, die Größe der Daten an der Adresse zu messen. Wenn Sie das*
vergessen und stattdessensizeof(ptr1)
schreiben, wird die Größe des Zeigers selbst gemessen, also die (normalerweise) 8 Bytes, die zum Speichern einer Speicheradresse erforderlich sind.Hinweis: Der
sizeof
Operator kann nicht messen, wie viel dynamischer Speicher zugewiesen ist. Beim Messen des dynamischen Speichers wird nur die Größe des Datentyps des Speichers angegeben. Wenn Sie beispielsweise Speicherplatz für 5Float
Werte reservieren, gibt dersizeof
Operator 4 zurück. Dies ist die Anzahl der Bytes, die für einen einzelnenFloat
Wert benötigt werden.
Lassen Sie uns das dynamische Gedächtnis nutzen, um das obige Schülerbeispiel zu verbessern.
Wie bereits erwähnt, können wir sizeof
nicht verwenden, um zu messen, wie viel Speicher zugewiesen wurde. Wir müssen dies berechnen, indem wir die Anzahl der Elemente mit der Größe des Datentyps multiplizieren:
Beispiel
int *students;
int numStudents = 12;
students = calloc(numStudents, sizeof(*students));
printf("%d", numStudents * sizeof(*students)); // 48 bytes
Hinweise
Wenn Sie mit dynamischer Speicherzuweisung arbeiten, sollten Sie am Ende des Programms auch auf Fehler und freien Speicher prüfen. In den nächsten Kapiteln erfahren Sie mehr darüber.
Stapelspeicher
Der Vollständigkeit halber sei noch der Stapelspeicher erwähnt. Stapelspeicher ist eine Art dynamischer Speicher, der für Variablen reserviert ist, die innerhalb von Funktionen deklariert werden. Innerhalb einer Funktion deklarierte Variablen verwenden Stapelspeicher und keinen statischen Speicher.
Wenn eine Funktion aufgerufen wird, wird Stapelspeicher für die Variablen in der Funktion reserviert. Wenn die Funktion zurückkehrt, wird der Stapelspeicher freigegeben.
Es ist gut, sich des Stapelspeichers bewusst zu sein, um die Speichernutzung von verschachtelten Funktionsaufrufen und Rekursionen bewältigen zu können. Rekursionen, die sich zu oft wiederholen, können zu viel Stapelspeicher beanspruchen. Wenn das passiert, nennt man das einen Stapelüberlauf.