Speicherverwaltung
Dynamische Speicherallokation
Grundlegende Speicherallokationsfunktionen
char *str = malloc(50 * sizeof(char)); // Speicher allozieren
if (str == NULL) {
// Fehler bei der Allokation behandeln
fprintf(stderr, "Speicherallokation fehlgeschlagen\n");
exit(1);
}
// Die Zeichenkette verwenden
strcpy(str, "Hello, LabEx!");
// Dynamisch allozierten Speicher immer freigeben
free(str);
Speicherallokationsstrategien
graph TD
A[Speicherallokation]
A --> B[malloc()]
A --> C[calloc()]
A --> D[realloc()]
A --> E[free()]
Speicherallokationsmethoden
Funktion |
Zweck |
Verhalten |
malloc() |
Grundlegende Allokation |
Nicht initialisierter Speicher |
calloc() |
Allokation mit Initialisierung |
Speicher mit Nullen gefüllt |
realloc() |
Größe der Allokation ändern |
Bestehende Daten werden beibehalten |
Sichere Zeichenkettenallokation
char* create_string(size_t length) {
char *new_str = malloc((length + 1) * sizeof(char));
if (new_str == NULL) {
return NULL; // Allokation fehlgeschlagen
}
new_str[length] = '\0'; // Null-Terminierung sicherstellen
return new_str;
}
Vermeidung von Speicherlecks
char* process_string(const char* input) {
char* result = malloc(strlen(input) + 1);
if (result == NULL) {
return NULL;
}
strcpy(result, input);
return result;
}
// Richtige Verwendung
char* str = process_string("Beispiel");
if (str != NULL) {
// Zeichenkette verwenden
free(str); // Immer freigeben
}
Erweiterte Speicherverwaltung
Umordnen von Zeichenketten
char* expand_string(char* original, size_t new_size) {
char* expanded = realloc(original, new_size);
if (expanded == NULL) {
free(original); // Original freigeben, falls realloc fehlschlägt
return NULL;
}
return expanded;
}
Häufige Fallstricke
- Vergessen, allozierten Speicher freizugeben
- Verwenden von Speicher nach Freigabe
- Pufferüberlauf
- Falsche Speichergrößenberechnungen
Best Practices
- Immer die Ergebnisse der Allokation überprüfen
- Speicher freigeben, wenn er nicht mehr benötigt wird
- Valgrind zur Erkennung von Speicherlecks verwenden
- StapgetAllokation bevorzugen, wenn möglich
Bei LabEx empfehlen wir eine sorgfältige Speicherverwaltung, um robuste C-Programme zu erstellen.
Speicherverfolgungsmethode
typedef struct {
char* data;
size_t size;
} SafeString;
SafeString* create_safe_string(size_t length) {
SafeString* safe_str = malloc(sizeof(SafeString));
if (safe_str == NULL) return NULL;
safe_str->data = malloc(length + 1);
if (safe_str->data == NULL) {
free(safe_str);
return NULL;
}
safe_str->size = length;
safe_str->data[length] = '\0';
return safe_str;
}
void free_safe_string(SafeString* safe_str) {
if (safe_str != NULL) {
free(safe_str->data);
free(safe_str);
}
}