Memory Example

0

Beispiel für Speicherverwaltung aus der Praxis

Um ein praktisches Beispiel für dynamischen Speicher zu demonstrieren, haben wir ein Programm erstellt, das Listen beliebiger Länge erstellen kann.

Normale Arrays in C haben eine feste Länge und können nicht geändert werden, aber mit dynamischem Speicher können wir beliebig lange Listen erstellen:

Beispiel

struct list {
  int *data; // Points to the memory where the list items are stored
  int numItems; // Indicates how many items are currently in the list
  int size; // Indicates how many items fit in the allocated memory
};

void addToList(struct list *myList, int item);

int main() {
  struct list myList;
  int amount;

  // Create a list and start with enough space for 10 items
  myList.numItems = 0;
  myList.size = 10;
  myList.data = malloc(myList.size * sizeof(int));

  // Find out if memory allocation was successful
  if (myList.data == NULL) {
    printf("Memory allocation failed");
    return 1; // Exit the program with an error code
  }

  // Add any number of items to the list specified by the amount variable
  amount = 44;
  for (int i = 0; i < amount; i++) {
    addToList(&myList, i + 1);
  }

  // Display the contents of the list
  for (int j = 0; j < myList.numItems; j++) {
    printf("%d ", myList.data[j]);
  }

  // Free the memory when it is no longer needed
  free(myList.data);
  myList.data = NULL;

  return 0;
}

// This function adds an item to a list
void addToList(struct list *myList, int item) {

  // If the list is full then resize the memory to fit 10 more items
  if (myList->numItems == myList->size) {
    myList->size += 10;
    myList->data = realloc( myList->data, myList->size * sizeof(int) );
  }

  // Add the item to the end of the list
  myList->data[myList->numItems] = item;
  myList->numItems++;
}

Zeiger auf Strukturen: Dieses Beispiel hat einen Zeiger auf die Struktur myList. Da wir einen Zeiger auf die Struktur statt auf die Struktur selbst verwenden, verwenden wir die Pfeilsyntax (->), um auf die Mitglieder der Struktur zuzugreifen.

Beispiel erklärt

Dieses Beispiel besteht aus drei Teilen:

  • Eine Struktur myList, die die Daten einer Liste enthält
  • Die main() Funktion mit dem darin enthaltenen Programm.
  • Eine Funktion addToList(), die ein Element zur Liste hinzufügt

Die myList Struktur

Die myList Struktur enthält alle Informationen zur Liste, einschließlich ihres Inhalts. Sie besteht aus drei Mitgliedern:

  • data – Ein Zeiger auf den dynamischen Speicher, der den Inhalt der Liste enthält
  • numItems – Gibt die Anzahl der Elemente an, die die Liste hat
  • Größe – Gibt an, wie viele Elemente in den zugewiesenen Speicher passen

Wir verwenden eine Struktur, damit wir all diese Informationen einfach an eine Funktion übergeben können.

Die main() Funktion

Die Funktion main() beginnt mit der Initialisierung der Liste mit Platz für 10 Elemente:

// Create a list and start with enough space for 10 items
myList.numItems = 0;
myList.size = 10;
myList.data = malloc(myList.size * sizeof(int));

myList.numItems wird auf 0 gesetzt, da die Liste zu Beginn leer ist.

myList.size verfolgt, wie viel Speicher reserviert ist. Wir setzen es auf 10, da wir genug Speicher für 10 Elemente reservieren.

Anschließend reservieren wir den Speicher und speichern einen Zeiger darauf in myList.data.

Anschließend führen wir eine Fehlerprüfung durch, um herauszufinden, ob die Speicherzuweisung erfolgreich war:

// Find out if memory allocation was successful
if (myList.data == NULL) {
  printf("Memory allocation failed");
  return 1; // Exit the program with an error code
}

Wenn alles in Ordnung ist, fügt eine Schleife mithilfe der Funktion addToList() 44 Elemente zur Liste hinzu:

// Add any number of items to the list specified by the amount variable
amount = 44;
for (int i = 0; i < amount; i++) {
  addToList(&myList, i + 1);
}

Im obigen Code ist &myList ein Zeiger auf die Liste und i + 1 eine Zahl, die wir der Liste hinzufügen möchten. Wir haben i + 1 gewählt, damit die Liste bei 1 statt bei 0 beginnt. Sie können jede beliebige Zahl wählen, die der Liste hinzugefügt werden soll.

Nachdem alle Elemente zur Liste hinzugefügt wurden, druckt die nächste Schleife den Inhalt der Liste.

// Display the contents of the list
for (int j = 0; j < myList.numItems; j++) {
  printf("%d ", myList.data[j]);
}

Wenn wir mit dem Drucken der Liste fertig sind, geben wir den Speicher frei, um Speicherlecks zu verhindern.

// Free the memory when it is no longer needed
free(myList.data);
myList.data = NULL;

Die Funktion addToList()

Unsere Funktion addToList() fügt der Liste ein Element hinzu. Sie benötigt zwei Parameter:

void addToList(struct list *myList, int item)
  1. Ein Zeiger auf die Liste.
  2. Der Wert, der der Liste hinzugefügt werden soll.

Die Funktion prüft zunächst, ob die Liste voll ist, indem sie die Anzahl der Elemente in der Liste mit der Größe der Liste vergleicht. Wenn die Liste voll ist, wird der Speicher neu zugewiesen, um 10 weitere Elemente unterzubringen:

// If the list is full then resize the memory to fit 10 more items
if (myList->numItems == myList->size) {
  myList->size += 10;
  myList->data = realloc( myList->data, myList->size * sizeof(int) );
}

Schließlich fügt die Funktion das Element am Ende der Liste hinzu. Der Index bei myList->numItems befindet sich immer am Ende der Liste, da er bei jedem Hinzufügen eines neuen Elements um 1 erhöht wird.

// Add the item to the end of the list
myList->data[myList->numItems] = item;
myList->numItems++;

Warum reservieren wir 10 Artikel auf einmal?

Bei der Optimierung handelt es sich um einen Balanceakt zwischen Speicher und Leistung. Auch wenn wir Speicher zuweisen, den wir nicht verwenden, kann eine zu häufige Neuzuweisung von Speicher ineffizient sein. Es besteht ein Gleichgewicht zwischen der Zuweisung von zu viel Speicher und der zu häufigen Speicherzuweisung.

Wir haben für dieses Beispiel die Zahl 10 gewählt, aber es hängt davon ab, wie viele Daten Sie erwarten und wie oft sie sich ändern. Wenn wir beispielsweise im Voraus wissen, dass wir genau 44 Elemente haben werden, können wir Speicher für genau 44 Elemente zuweisen und dies nur einmal tun.

Nach oben scrollen