Freigeben des zugewiesenen Speichers für Knoten in der verknüpften Liste in C
Heute werden wir sehen, wie man den zugewiesenen Speicher für Knoten in der verknüpften Liste in C freigibt oder freigibt.
Freigeben des zugewiesenen Speichers für Knoten in der verknüpften Liste in C
In diesem Artikel verwenden wir die Funktion free()
, um den Speicher freizugeben, der von der Funktion malloc()
reserviert oder zugewiesen wurde. Das heißt, wann immer wir die Funktion malloc()
aufrufen, müssen wir irgendwann die entsprechende Funktion free()
aufrufen, um den Speicher freizugeben.
Bei der Verwendung der verketteten Liste in der C-Programmierung wird jedem Knoten einer verketteten Liste ein Speicherplatz zugewiesen, sobald die Funktion malloc()
aufgerufen wird. Daher geben wir den zugewiesenen Speicher frei, indem wir die Methode free()
aufrufen, wenn der Knoten oder die vollständige verkettete Liste nicht mehr benötigt wird.
Angenommen, wir haben eine verknüpfte Liste, die die 3 Knoten enthält, und wir haben entschieden, dass diese verknüpfte Liste jetzt nicht erforderlich ist. Wir können die Schleife verwenden, um über die verknüpfte Liste zu iterieren und den zugewiesenen Speicher für jeden Knoten freizugeben.
Denken Sie daran, dass wir nicht erwarten können, dass die gesamte Struktur einer verknüpften Liste freigegeben wird, indem die Funktion free()
vom Root-Knoten aufgerufen wird. Um es praktisch zu verstehen, verwenden wir zwei Codebeispiele.
- Drucken Sie eine vollständige verkettete Liste und geben Sie den zugewiesenen Speicher für alle Knoten frei
- Drucken Sie den aktuellen Knoten, speichern Sie den Zeiger des nächsten Knotens und geben Sie den Speicher für den aktuellen Knoten frei. Dies bedeutet, dass wir den zugewiesenen Speicher in einer Schleife drucken und freigeben.
Drucken der gesamten verknüpften Liste und Freigeben des zugewiesenen Speichers
Um dieses Szenario praktisch zu lernen, definieren wir die verknüpften Listenknoten wie folgt. Beachten Sie, dass wir die Struktur rekursiv definieren, was die C-Programmierung erlaubt.
Außerdem verwenden wir typedef struct
anstelle von struct
, nur um einen organisierteren und saubereren Code zu schreiben. Der Unterschied zwischen typedef struct
und struct
wird ausführlich hier erklärt.
typedef struct node {
int data;
struct node* next;
} nodes;
Füllen Sie alle Knoten mit der Funktion makeList()
. Hier haben wir nur drei Knoten in der verknüpften Liste.
struct node* makeList() {
nodes* headNode = NULL;
nodes* secondNode = NULL;
nodes* thirdNode = NULL;
headNode = malloc(sizeof(nodes));
secondNode = malloc(sizeof(nodes));
thirdNode = malloc(sizeof(nodes));
headNode->data = 1;
headNode->next = secondNode;
secondNode->data = 2;
secondNode->next = thirdNode;
thirdNode->data = 3;
thirdNode->next = NULL;
return headNode;
}
Die Methode printList()
(unten) iteriert über die verknüpfte Liste und druckt jeden Listenknoten. Hier haben wir den currentNode
erstellt, der auf den headNode
verweist.
Dann verwenden wir eine while
-Schleife, um zu prüfen, ob der currentNode
NULL
ist. Wenn nicht, drucken Sie die currentNode
-Daten aus und speichern Sie die Adresse des nächsten Knotens in currentNode
.
Dieser Vorgang wird fortgesetzt, bis der currentNode
gleich NULL
ist.
void printList(nodes* headNode) {
nodes* currentNode = headNode;
while (currentNode != NULL) {
printf("The current element is %d\n", currentNode->data);
currentNode = currentNode->next;
}
}
Nach dem Drucken der gesamten verknüpften Liste gibt die Funktion freeList()
(unten) den zugewiesenen Speicher für jeden Knoten frei.
Die Funktion freeList()
prüft, ob der headNode
NULL
ist. Wenn es NULL
ist, ist die Liste leer, also kehren wir sofort von dieser Funktion zurück.
Speichern Sie zweitens den headNode
in einer currentNode
-Variablen und lassen Sie den headNode
auf den unmittelbar nächsten Knoten in unserer Liste zeigen. Wir machen das in headNode = headNode->next;
.
Drittens geben wir den zugewiesenen Speicher mit free(currentNode)
sicher frei. Nun zeigt der headNode
auf die verbleibende Liste und geht zurück zum ersten Schritt.
void freeList(nodes* headNode) {
nodes* currentNode;
while (headNode != NULL) {
currentNode = headNode;
headNode = headNode->next;
free(currentNode);
}
}
Schließlich verwenden wir die Methode main()
, um die Funktionen wie folgt aufzurufen und das Ziel zu erreichen.
int main() {
nodes* headNode = makeList();
printList(headNode);
freeList(headNode);
return 0;
}
Vollständiger Beispielcode
Das gesamte Programm sieht wie unten gezeigt aus, wenn wir alle Code-Blöcke zusammenstellen.
#include <stdio.h>
typedef struct node {
int data;
struct node* next;
} nodes;
struct node* makeList() {
nodes* headNode = NULL;
nodes* secondNode = NULL;
nodes* thirdNode = NULL;
headNode = malloc(sizeof(nodes));
secondNode = malloc(sizeof(nodes));
thirdNode = malloc(sizeof(nodes));
headNode->data = 1;
headNode->next = secondNode;
secondNode->data = 2;
secondNode->next = thirdNode;
thirdNode->data = 3;
thirdNode->next = NULL;
return headNode;
}
void printList(nodes* headNode) {
nodes* currentNode = headNode;
while (currentNode != NULL) {
printf("The current element is %d\n", currentNode->data);
currentNode = currentNode->next;
}
}
void freeList(nodes* headNode) {
nodes* currentNode;
while (headNode != NULL) {
currentNode = headNode;
headNode = headNode->next;
free(currentNode);
}
}
int main() {
nodes* headNode = makeList();
printList(headNode);
freeList(headNode);
return 0;
}
Ausgang:
The current element is 1
The current element is 2
The current element is 3
Drucken Sie den aktuellen Knoten, speichern Sie den Zeiger für den nächsten Knoten und geben Sie den zugewiesenen Speicher für den aktuellen Knoten frei
In diesem Codebeispiel drucken wir den aktuellen Knoten, speichern die Adresse für den nächsten Knoten und geben den zugewiesenen Speicher für den aktuellen Knoten frei.
Bis auf zwei Dinge ist alles gleich wie im vorherigen Beispiel. Erstens haben wir die Funktion freeList()
nicht und zweitens haben wir printAndFreeList()
statt printList()
.
In der Funktion printAndFreeList()
iterieren wir über die Liste, drucken den aktuellen Knoten, speichern den Zeiger für den Rest der verknüpften Liste und geben den Speicher für den aktuellen Knoten frei.
Dieser Vorgang wird fortgesetzt, bis die NULL
gefunden wird.
void printAndFreeList(nodes* currentNode) {
nodes* tempNode;
while (currentNode != NULL) {
tempNode = currentNode;
printf("The current element is %d\n", currentNode->data);
currentNode = currentNode->next;
free(tempNode);
}
}
Vollständiger Beispielcode
Das ganze Programm sieht wie folgt aus.
#include <stdio.h>
typedef struct node {
int data;
struct node* next;
} nodes;
struct node* makeList() {
nodes* headNode = NULL;
nodes* secondNode = NULL;
nodes* thirdNode = NULL;
headNode = malloc(sizeof(nodes));
secondNode = malloc(sizeof(nodes));
thirdNode = malloc(sizeof(nodes));
headNode->data = 1;
headNode->next = secondNode;
secondNode->data = 2;
secondNode->next = thirdNode;
thirdNode->data = 3;
thirdNode->next = NULL;
return headNode;
}
void printAndFreeList(nodes* currentNode) {
nodes* tempNode;
while (currentNode != NULL) {
tempNode = currentNode;
printf("The current element is %d\n", currentNode->data);
currentNode = currentNode->next;
free(tempNode);
}
}
int main() {
nodes* headNode = makeList();
printAndFreeList(headNode);
return 0;
}
Ausgang:
The current element is 1
The current element is 2
The current element is 3