A canonical insertion routine, followed by five small patterns that show up everywhere when working with linked-list pointers in C.
Allocate a new node, point its next at what currently follows, then redirect the previous node's next to the new node.
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = 15;
newNode->next = first->next; /* new node points to second node */
first->next = newNode; /* first node now points to new node */
newNode->next before reassigning first->next. Otherwise the only reference to the second node is lost the moment first->next is overwritten — and everything past it leaks.Each snippet is a single, self-contained idea — no surrounding function or boilerplate.
A node holds its data and a pointer to another node of the same type — the recursive shape that makes a linked list possible.
struct Node {
int data;
struct Node* next;
};
Reserve memory, set the data, and explicitly null the next pointer so it isn't left pointing at garbage.
struct Node* head = (struct Node*)malloc(sizeof(struct Node));
head->data = 10;
head->next = NULL;
A second pointer walks the list without disturbing head, stopping when it hits the terminator.
struct Node* temp = head;
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
A double pointer lets the caller's head variable be reassigned from inside another scope.
struct Node** headRef;
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = 5;
newNode->next = *headRef;
*headRef = newNode;
Walk forward until prev->next is the doomed node, splice it out, then return its memory.
struct Node* prev = head;
while (prev->next != NULL && prev->next->data != target)
prev = prev->next;
struct Node* del = prev->next;
prev->next = del->next;
free(del);