Linked Lists
How do we stitch together a series of values into a ‘list,’ even though there isn’t a list datatype in C?
Here is some code for that. We’re using malloc, loops, pointers, and creating data structures (structs) called nodes.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int number;
struct node *next;
}
node;
int main(int argc, char *argv[])
{
node *list = NULL;
for (int i = 1; i < argc; i++)
{
int number = atoi(argv[i]);
node *n = malloc(sizeof(node));
if (n == NULL)
{
return 1;
}
n->number = number;
n->next = NULL;
n->next = list;
list = n;
}
for(node *ptr = list; ptr !=NULL; ptr = ptr->next)
{
printf("%i\n", ptr->number);
ptr = ptr->next;
}
ptr = list;
while (ptr !=NULL);
;
{
node *next = ptr->next;
free(ptr);
ptr = next;
}
}
x—x
So, I’ve actually located a number of errors in my code with the help of my favorite debugger: ChatGPT.
First, I was not properly identifying ptr in the scope where it was being used. It was declared inside of the forloop but I was trying to use it again later, when it was then out of scope.
To rectify this error, I declared node *ptr = NULL; at the top of my code.
Then I ran into another error:
$ make list
list.c:32:15: error: declaration shadows a local variable [-Werror,-Wshadow] for(node *ptr = list; ptr !=NULL; ptr = ptr->next) ^ list.c:14:11: note: previous declaration is here node *ptr = NULL; ^ fatal error: too many errors emitted, stopping now [-ferror-limit=] 2 errors generated. make: *** [<builtin>: list] Error 1
This told me that I declared ptr twice in the same scope, which confused me and caught me off guard. I learned that this was called shadowing, which is when you declare the same variable twice within a given loop.
To fix this, I removed node * from the for(ptr = list; ptr !=NULL; ptr = ptr→next) line.
Then I got a segmentation fault error.
Turns out I had an extra ptr = ptr→next statement in my forloop so it skipped stuff in my list, then tried to access an element that didn’t exist yet, thanks to the broken forloop—i.e, it was trying to jump the gun and caused a memory error.
However, I appeared to have made another error somewhere, as my terminal kept breaking, so I immediately thought I’d created an infinite loop, because the terminal wouldn’t reprint $ (assuming the loop hadn’t ended because there must not have been a return 0; occurring somewhere within the program). Then I’d forgotten to actually remove that semicolon at the right time, hence the bug.
So, I removed ptr = ptr→next from under the printf line. I also removed a buggy semicolon I had placed here:
while (ptr !=NULL)
;
{
node *next = ptr→next;
free(ptr);
ptr = next
}
Now, with the additional semicolon now banned from the circus, the program runs fine and…
…lists some numbers.
Fascinating.
Can I get to Python now?
x—x
Thanks for reading.
Judson