In C sind Arrays eine grundlegende Struktur zur Speicherung einer geordneten Menge von Elementen des gleichen Typs. Sie bieten einen schnellen Zugriff über Indizes und sind eng mit der Arbeit mit Zeigern verbunden. Arrays können statisch, automatisch (auf dem Stack) oder dynamisch (im Heap) deklariert werden. Der Typ der Zuweisung wirkt sich auf die Lebensdauer des Arrays, die Verfügbarkeit in verschiedenen Teilen des Codes und die Anforderungen an das Speicher-Management aus.
Hintergrund
Ursprüngliches C erlaubte nur die Definition von statischen und automatischen Arrays, aber mit der Einführung der dynamischen Speicherzuweisung (Funktionen malloc, calloc, free) entstanden neue Entwurfsmuster, die die Flexibilität des Codes erhöhten.
Problem
Entwickler machen häufig Fehler bei den Größen, der Lebensdauer und der Bereinigung von Arrays, was zu Speicherlecks, Race-Conditions und Speicherbeschädigung führt.
Lösung
Sorgfältige Auswahl des Speichertyps je nach Aufgabe, genaues Verfolgen der Initialisierung und rechtzeitige Freigabe des Speichers für dynamische Arrays.
Codebeispiel:
#include <stdio.h> #include <stdlib.h> int main() { // Automatisch (auf dem Stack) int auto_arr[5] = {1,2,3,4,5}; // Statisch (lebt solange das Programm läuft) static int static_arr[5]; // Dynamisch (im Heap) int *dyn_arr = malloc(5 * sizeof(int)); for (int i = 0; i < 5; i++) dyn_arr[i] = i * 2; // Verwendung for (int i = 0; i < 5; i++) printf("%d ", dyn_arr[i]); printf(" "); free(dyn_arr); return 0; }
Wichtige Merkmale:
Kann man die Größe eines dynamischen Arrays mit sizeof herausfinden?
Nein, sizeof(ptr) für ein dynamisches Array gibt die Größe des Zeigers zurück, nicht die des Arrays. Es ist notwendig, die Größe manuell zu speichern oder eine separate Variable zu verwenden.
int* arr = malloc(10 * sizeof(int)); printf("%zu ", sizeof(arr)); // Größe des Zeigers, nicht des Arrays
Was passiert bei einem Überlauf des Arrays?
In C gibt es keine automatische Überprüfung der Array-Grenzen: Ein Zugriff außerhalb der Grenzen führt zu undefined behavior. Fehler werden nur zur Laufzeit erkannt oder gar nicht.
Kann man ein lokales (automatisches) Array aus einer Funktion zurückgeben?
Nein! Ein Array, das innerhalb einer Funktion deklariert wird, wird nach deren Ende gelöscht. Die Rückgabe eines solchen Arrays führt zu einem Zugriff auf bereits freigegebenen Speicher.
int* create_wrong_array() { int arr[10]; return arr; // Fehler: Rückgabe eines Zeigers auf den Stack }
Ein Entwickler erstellt ein Array auf dem Stack und gibt einen Zeiger darauf aus der Funktion zurück. Das Programm stürzt manchmal ab oder gibt Müll zurück.
Vorteile:
Nachteile:
Verwendung von dynamischer Zuweisung mit Übergabe der Dimension zusammen mit dem Zeiger, Speicherbereinigung mit free. Alle Fälle der Speicherfreigabe werden mit Unit-Tests überprüft.
Vorteile:
Nachteile: