Graph representation with dynamic linked lists - c

I start by saying I am quite new to C and right now, I struggle with some very non intuitive mistakes. I've tried for quite a while now to reach at some solution, but I am always reaching a dead end.
I am trying to build a couple of functions for inserting and displaying a graph via dynamic linked lists. At compile time everything works just fine, but the elements seem not to be well displayed. Actually, just like in the image below, only the first element of the node is displayed.
So the question is what is causing these errors and warnings and what should I do to remove them?
If you take a look at the code below, you will see that it has a few warnings(I don't know why they appear - I am using Code Blocks in Ubuntu with the GNU compiler) and also problems at displaying the elements of the graph. The problem lies most likely in the display_graph function, but I can't realize where.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct AdjListNode {
int dest;
struct LIST_NODE *next;
} LIST_NODE;
typedef struct AdjList {
struct LIST_NODE *head;
} ADJACENCY_LIST;
LIST_NODE *create_node(int dest) {
LIST_NODE *nod;
if(dest<0) exit(0);
nod = (LIST_NODE*)malloc(sizeof(LIST_NODE));
if(nod==NULL) {
printf("Problems at memory allocation!");
exit(0);
}
nod->dest = dest;
nod->next = NULL;
return (LIST_NODE*)nod;
}
void display_graph(ADJACENCY_LIST *v) {
int s, i;
LIST_NODE *nod;
s = sizeof(v);
for(i=0;i<=s;i++) {
nod = v[i].head;
//citeste lista cu head in primul nod
while(nod!=NULL) {
printf("Data from node: %d \n", nod->dest);
nod = nod->next;
}
}
}
int main()
{
int n; //number of graph nodes
int i; //just a counter
int dest; dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative
char c;
ADJACENCY_LIST *t;
printf("The number of nodes of the graph: ");
scanf("%d", &n);
t = (ADJACENCY_LIST*)malloc(n*sizeof(ADJACENCY_LIST));
/* We make a loop for the nodes and each node has a while thru which I make the links */
for(i=0;i<n;i++) {
c = 'D'; // Initializing
printf("Specify the links of the node %d with the others:\n", i);
int contor; contor = 0;
while(c=='D') {
LIST_NODE *nod;
printf("The link with node: ");
scanf("%d%*c", &dest);
if(dest>=0){
nod = create_node(dest);
if(contor==0) t[i].head = (LIST_NODE*)nod; // just make the first node a head node
} else nod = NULL;
//verificam daca vrem sa continuam
printf("Do you want to link any other node to %d?(D to add, anything else STOP\n)", i);
c = getchar();
contor++; //increment counter
}
// inchidem lista
}
display_graph(t);
return 0;
}
Any help will be greatly appreciated!
EDIT:
As Christhofe(confirmed the problem) and Abhishek Vasisht pointed out the size of the vector v returned actually the size of the pointer.
But, there are still some warnings which I don't know why they still appear...all are
||=== Build: Debug in Grafuri1 (compiler: GNU GCC Compiler) ===|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c||In function ‘display_graph’:|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|33|warning: assignment from incompatible pointer type|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|38|warning: assignment from incompatible pointer type|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|28|warning: unused variable ‘s’ [-Wunused-variable]|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c||In function ‘main’:|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|71|warning: assignment from incompatible pointer type|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|76|warning: assignment from incompatible pointer type|
||=== Build finished: 0 error(s), 5 warning(s) (0 minute(s), 0 second(s)) ===|
The main thing is the program is functional now. Thanks a lot guys! Really helpful!!

Try this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct AdjListNode {
int dest;
struct LIST_NODE *next;
} LIST_NODE;
typedef struct AdjList {
struct LIST_NODE *head;
} ADJACENCY_LIST;
LIST_NODE *create_node(int dest) {
LIST_NODE *nod;
if (dest < 0) exit(0);
nod = (LIST_NODE*)malloc(sizeof(LIST_NODE));
if (nod == NULL) {
printf("Problems at memory allocation!");
exit(0);
}
nod->dest = dest;
nod->next = NULL;
return (LIST_NODE*)nod;
}
void display_graph(ADJACENCY_LIST *v,int values) {
int s, i;
LIST_NODE *nod;
for (i = 0; i < values; ++i)
{
nod = v[i].head;
printf("Data from node: %d \n", i);
while (nod != NULL)
{
printf("Data : %d \n", nod->dest);
nod = nod->next;
}
}
}
int main()
{
int n; //number of graph nodes
int i; //just a counter
int dest; dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative
char* c = (char*)(malloc(sizeof(char)));
ADJACENCY_LIST *t;
LIST_NODE *last_added;
printf("The number of nodes of the graph: ");
scanf("%d", &n);
t = (ADJACENCY_LIST*)calloc(n,sizeof(ADJACENCY_LIST));
/* We make a loop for the nodes and each node has a while thru which I make the links */
for (i = 0; i < n; i++) {
//c = 'D'; // Initializing
printf("Specify the links of the node %d with the others:\n", i);
int contor; contor = 0;
do {
LIST_NODE *nod;
printf("The link with node: ");
scanf("%d", &dest);
if (dest >= 0) {
nod = create_node(dest);
if (contor == 0)
{
t[i].head = (LIST_NODE*)nod; // just make the first node a head node
last_added = nod;
}
else
{
last_added->next = nod;
last_added = nod;
}
}
//verificam daca vrem sa continuam
printf("Do you want to link any other node to %d?(D to add, anything else STOP\n)", i);
fflush(stdin);
*c = getchar();
contor++; //increment counter
} while (*c == 'D');
}
display_graph(t,n);
return 0;
}

the following code compiles cleanly, works.
It does not have the capability of having a list of nodes for each entry in the first level list of pointers.
You can easily add that feature.
You also need to add the feature of passing each malloc'd node to free()
especially when an error has occurred
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct AdjListNode
{
int dest;
struct AdjListNode *next;
} ;
// declare list of pointers to nodes
static struct AdjListNode **head = NULL;
struct AdjListNode *create_node(int dest)
{
struct AdjListNode *nod;
nod = malloc(sizeof(struct AdjListNode));
if(nod==NULL)
{
perror(" malloc failed" );
printf("Problems at memory allocation!");
exit(-1);
}
// implied else, malloc successful
nod->dest = dest;
nod->next = NULL;
return nod;
} // end function: create_node
int main( void )
{
int n; //number of graph nodes
int i; //just a counter
int dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative
printf("The number of nodes of the graph: ");
if( 1 != scanf("%d", &n) )
{ // then scanf failed
perror( "scanf for number of nodes failed" );
exit( -1 );
}
// implied else, scanf successful
// set ptr to list of node pointers
head = malloc(n*sizeof(struct AdjList*));
if( NULL == head )
{ // then malloc failed
perror( "malloc failed for list of pointers to nodes" );
exit( -1 );
}
// implied else, malloc successful
// initialize list of pointers (makes for easier cleanup, especially when a failure occurs
memset( head, 0x00, n*sizeof(struct AdjList*) );
/* We make a loop for the nodes and each node has a while thru which I make the links */
for(i=0;i<n;i++)
{
printf("Enter Dest value for %d of %d:", i, n);
if( 1 != scanf("%d", &dest) ) // note %d will skip over leading white space like newlines
{ // then scanf failed
perror( "scanf for dest value failed" );
exit(-1);
}
// implied else, scanf successful
if(dest>=0)
{
head[i] = create_node(dest);
}
else
{
printf( "Dest value must be >= 0\n" );
}
//verificam daca vrem sa continuam
// inchidem lista
} // end for
return 0;
} // end function: main

Related

Why my code linked list don't return NULL and SEG FAULT instead

I try to code a pattern to copy, duplicate a linked list in a struct pointer, but when my last element is print that is cause a seg fault and the last element return an address of type 0x0or 0xF00000000000. I don't find where I miss something in my code, may be when I duplicate int dup(t_child **ref, t_child *src) the linked list in my struct, but my knowledge in the Cis limited.
below I try to make a simple code to reproduce my problem.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct s_child t_child;
struct s_child {
int id;
t_child *next;
};
typedef struct s_mother t_mother;
struct s_mother {
t_child *child;
t_mother *next;
};
int add_child(t_child **ref, int rank) {
t_child *temp;
temp = NULL;
if(!(temp = (t_child*)malloc(sizeof(t_child))))
return (0);
temp->id = rank;
temp->next = (*ref);
(*ref) = temp;
return(1);
}
int dup(t_child **ref, t_child *src) {
int rank = 0;
int ret = 0;
while(src) {
ret = add_child(ref, rank);
if(!ret)
break;
rank++;
src = src->next;
}
return(ret);
}
int add_mother(t_mother **ref, t_child *c) {
t_mother *temp;
temp = NULL;
if(!(temp = (t_mother*)malloc(sizeof(t_mother))))
return (0);
dup(&temp->child, c);
temp->next = (*ref);
(*ref) = temp;
return(1);
}
int main() {
t_child *c;
c = NULL;
for(int i = 0 ; i < 4 ; i++) {
add_child(&c, i);
}
t_mother *m;
m = NULL;
add_mother(&m, c);
while(m->child) {
printf("id: %i\n",m->child->id);
m->child = m->child->next;
printf("m->child %p\n", m->child);
if(m->child == NULL)
printf("m->child NULL\n");
}
return(0);
}
terminal output
id: 3
m->child 0x7fb302402b60
id: 2
m->child 0x7fb302402b50
id: 1
m->child 0x7fb302402b40
id: 0
m->child 0xf000000000000000
[1] 16550 segmentation fault ./a.out
Hey did you check that your linked list ended with NULL or even setting the first pointer with NULL ?
When you "move" inside your linked list you must have NULL as last element, then in case like :
while(*ptr_on_list* != NULL)
you can't segfault.
So also check you stop "moving" in your linked list BEFORE you reach the NULL.
Hope i helped you, feel free to notice me if not

Segmentation fault when trying to print out a struct

I'm trying to make a code that will allow the user to input any amount of entries he wants, and then print them out (and other functions, still have to get to that). But when I try to launch the code it allows me to input the entries, but when I want to print them out, it doesn't register current.name or current.telNo (only prints out 1: has tel. No. ) and a segmentation error follows after it. Any idea how I can fix that.
#include <stdio.h>
#include <stdlib.h>
int listSize;
int counter = 0;
struct Entry {
char name[20];
char telNo[9];
struct Entry *next;
} current;
int main()
{
struct Entry *linkedList = (struct Entry * )malloc(sizeof(struct Entry));
struct Entry *current = linkedList;
first(current);
print(current);
return 0;
}
void first(struct Entry linkedList)
{
int i;
printf("enter list size: ");
scanf("%d", &listSize);
printf("Now enter entries one by one: \n");
for (i = 0; i < listSize; i++) {
counter++;
printf("Name: ");
scanf("%s", linkedList.name);
printf("Telephone: ");
scanf("%s", linkedList.telNo);
if (i != listSize -1) {
linkedList.next = (struct Entry *)malloc(sizeof(struct Entry));
linkedList = *linkedList.next;
} else {
linkedList.next = NULL;
}
}
}
void print(struct Entry linkedList)
{
int nr = 1;
printf("\nTelephone book is:\n");
while (current.name != NULL) {
printf("%d: %s has tel. No.\t%s\n", nr, current.name, current.telNo);
current = *current.next;
nr++;
}
}
Instead of . you should have used -> and in your print() you were traversing current instead of linkedList which was causing the issue. Also your functions definitions should come before its usage. Please check the below snippet, i have made the corresponding changes.
#include <stdio.h>
#include <stdlib.h>
int listSize;
int counter = 0;
struct Entry {
char name[20];
char telNo[9];
struct Entry *next;
} current;
void print(struct Entry *linkedList)
{
int nr = 1;
printf("\nTelephone book is:\n");
while (linkedList->name != NULL) {
printf("%d: %s has tel. No.\t%s\n", nr, linkedList->name, linkedList->telNo);
linkedList = linkedList->next;
nr++;
}
}
void first(struct Entry *linkedList)
{
int i;
printf("enter list size: ");
scanf("%d", &listSize);
printf("Now enter entries one by one: \n");
for (i = 0; i < listSize; i++) {
counter++;
printf("Name: ");
scanf("%s", linkedList->name);
printf("Telephone: ");
scanf("%s", linkedList->telNo);
if (i != listSize -1) {
linkedList->next = (struct Entry *)malloc(sizeof(struct Entry));
linkedList = linkedList->next;
} else {
linkedList->next = NULL;
}
}
}
int main()
{
struct Entry *linkedList = (struct Entry * )malloc(sizeof(struct Entry));
struct Entry *current = linkedList;
first(current);
print(current);
return 0;
}
while (current.name != NULL)
should be
while (current != NULL)
otherwise current = *current.next will become NULL and crash on the while condition
current.name is a pointer to reserved 20-byte area, which is always non-NULL.
I would initialize *next with NULL every time I allocate it (there are few ways to do that, easiest: assign NULL to it right after malloc). And do the check like that: if (current.next != NULL).
You also can check for current.name[0] != 0, but the first option is cleaner.
There are a number of errors in your code but, essentially two main 'points of confusion':
First, you seem to be confusing a structure (struct Entry) with a pointer-to-structure (as in, for example, struct Entry *next;).
Second, you have two different variables called current - one defined globally (which is the only one that is 'visible' to your print function), and another one defined locally inside main (this one will 'hide' the former).
Here is a corrected version of your code, with triple-slash (///) comments wherever I've made changes. Feel free to ask for further clarification and/or explanation.
#include <stdio.h>
#include <stdlib.h>
int listSize;
int counter = 0;
struct Entry {
char name[20];
char telNo[9];
struct Entry* next;
} *current; /// Here, we define a GLOBAL variable, "current" that is a POINTER to the struct
void first(struct Entry* linkedList); /// Put "Function Prototypes* here, so that "main" knows what they are
void print(struct Entry* linkedList); /// You need to pass POINTERS to structures, not the actual structures
int main()
{
struct Entry* linkedList = (struct Entry*)malloc(sizeof(struct Entry));
// struct Entry* current = linkedList; /// This declaration 'hides' the global variable
current = linkedList; /// Here, we (properly) assign the global pointer's value
first(current);
print(current);
return 0;
}
void first(struct Entry* linkedList) /// Pointer (see above)
{
int i;
printf("enter list size: ");
scanf("%d", &listSize);
printf("Now enter entries one by one: \n");
for (i = 0; i < listSize; i++) {
counter++;
printf("Name: ");
scanf("%s", linkedList->name); /// Use "->" instead of "." to get a pointer's member (and elsewhere)
printf("Telephone: ");
scanf("%s", linkedList->telNo); /// See above
if (i != listSize - 1) {
linkedList->next = (struct Entry*)malloc(sizeof(struct Entry)); /// See above
linkedList = linkedList->next; /// Again - changed here to use pointers!
}
else {
linkedList->next = NULL; /// See above
}
}
}
void print(struct Entry* linkedList) /// Pointer (see above)
{
int nr = 1;
printf("\nTelephone book is:\n");
while (current != NULL) { /// You need to check if "current" is not NULL before trying to access any of its members...
// while (current.name != NULL) {
printf("%d: %s has tel. No.\t%s\n", nr, current->name, current->telNo); /// Same "." to "->" changes as before
current = current->next; /// And again!
nr++;
}
}
There are other ways to 'fix' your code (and also improve it): for example, you never use the argument you pass to print, relying instead on the 'global' variable I mentioned earlier.

Linked List insertion in Beginning

I am trying basic creation of linked list using C. I have written the following code which is working up until first node but fails eventually on second one. I think the issue is where I am trying to display the node values in list separated by arrow(->). I think my logic is right but please correct me. Thanks in advance
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node
{
int number;
struct node *next;
};
typedef struct node NODE;
NODE *node1, *node2, *start, *save;
int main()
{
node1 = (NODE *)malloc(sizeof(NODE));
int i = 0;
start = NULL;
for(i = 0; i < 3; i++)
{
int inf;
printf("Enter node value:");
scanf("%d", &inf);
node1->number = inf;
node1->next = NULL;
if(start == NULL)
{
start = node1;
save = node1;
}
else
{
// save=start;
// start=node1;
// node1->next=save;
node1->next = start;
start = node1;
}
while(node1 != NULL)
{
printf("%d ->",node1->number);
node1 = node1->next;
}
}
return 0;
}
The issues are
How you're allocating your nodes for insertion (i.e. save for one, you're not).
How they're placed in the list once you fix the above.
Don't cast malloc in C programs (read here for why).
Fail to check the success of your scanf invoke.
Fail to check the success of your malloc invoke
Before you get discouraged, things you did correctly:
Did not mask a node pointer in a typedef
Properly included a MCVE for review
Prospected the things you may be doing wrong.
A very simple example of iterating three values into a linked list would look something like this:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int number;
struct node *next;
};
typedef struct node NODE;
int main()
{
NODE *head = NULL, *p;
int i = 0;
for(i = 0; i < 3; i++)
{
int inf;
printf("Enter node value:");
if (scanf("%d", &inf) == 1)
{
p = malloc(sizeof *p);
if (p != NULL)
{
p->number = inf;
p->next = head;
head = p;
}
else
{
perror("Failed to allocate new node");
return EXIT_FAILURE;
}
}
else
{
// failed to read data. break
break;
}
// report current linked list
printf("%d", p->number);
for (p=p->next; p; p = p->next)
printf(" -> %d", p->number);
fputc('\n', stdout);
}
// cleanup the linked list
while (head)
{
p = head;
head = head->next;
free(p);
}
head = NULL;
return 0;
}
Input
The values 1 2 3 are input upon being prompted:
Output
Enter node value:1
1
Enter node value:2
2 -> 1
Enter node value:3
3 -> 2 -> 1
Best of luck.
You should use malloc() inside for loop.
Since it is outside, same memory is being used.
As said by Vamsi, you should use malloc to put the nodes on the heap. You also generally shouldn't cast the output of malloc, it isn't needed. And then you could play around with making a doubly-linked list, where you also have a prev pointer inside your struct.

C program not recognizing null pointer

I'm trying to recurvisely implement an insert function in C, but I'm having all sorts of issues. I'm in an intro CS class and they started throwing C labs at us before we had ever worked with it before. Part of the issue is that the list pointer is not being recognized as NULL and I'm also pretty sure that I'm using malloc improperly.
#include <stdio.h>
#include <stdlib.h>
#define True 1
#define False 0
typedef int BOOLEAN;
struct Node{
int value;
struct Node *next;
};
void insert(int x, struct Node **pL){
printf("insert\n");
if(*pL == NULL){
printf("inside if\n");
struct Node *pN;
pN = (struct Node*) malloc(sizeof(struct Node));
(*pN).value = x;
(*pN).next = NULL;
return;
}
if (*pL != NULL){
printf("inside else\n");
insert(x, &(((*pL)->next)));
}
printf("end insert\n");
};
void printList(struct Node *L){
while (L != NULL){
printf("%d", (*L).value);
printList((*L).next);
}
return;
};
main(){
printf("main\n");
struct Node* L;
//L).next = NULL;
int i;
printf("for loop\n");
for (i = 3; i < 20; i+=2){
printf("%d\n", i);
insert(i, &L);
}
printList(L);
};
First of all, in main you need to initialise L:
struct Node* L = NULL;
Second, in insert when you allocate the new node pN, you are not assigning it to the pL, i.e., it doesn't get inserted. Put this right before the return; in insert:
*pL = pN;
(Also you could remove the return and change if (*pL != NULL) into else.)
Then, in printList you are both iterating with a while loop, and with recursion. Choose one, not both, e.g.,:
while (L) {
printf("%d\n", L->value);
L = L->next;
}
Also, throughout your code you can replace (*pointer_to_struct).field with pointer_to_struct->field for better style.

Linked list in C, is the list being constructed correctly?

I'm trying to implement a linked list abstraction, however I am running into problems. Once I create the linked list and add elements to it. When I print the list it only prints the first element in it in an infinite loop fashion, meaning that either the first element is linked to itself or the print function is incorrect. However, I can't find the problem, could someone help?
The following is the list abstraction:
typedef struct _friend {
char *firstname;
char *lastname;
char birthdate[9];
} friend;
typedef struct _node {
friend *value;
struct _node *next;
} node;
typedef struct _linkedlist {
node *head;
} linkedlist;
The program must follow this abstraction, as it is part of something bigger.
The following are the functions that should print the list and add a node to the beginning of the list:
/* addHead
*
* This function takes two parameters - a linked list and a friend.
* This creates a node for the linked list and connects the friend to the
* node. Then it adds the node to the head of the linked list.
*/
void addHead(linkedlist *llist, friend *f)
{
// create a node and put the friend in it
node *n = (node *)malloc(sizeof(node));
n->value = f;
n->next = NULL;
// if the list is empty
if (llist == NULL)
{
// this link is the entire list
llist->head = n;
printf("adding friend to null list\n");
}
// if the list is not empty
else
{
// make the new link's next pointer point to
// the first link in the list
n->next = llist->head;
printf("adding %s to head\n", n->value->firstname);
// make the head pointer point to the new link
llist->head = n;
}
}
/*
* printList
*
* This steps down through each of the nodes in a linked list and
* prints out the information stored in the friend to which the node points.
* Instead of automatically printing to the screen, it prints to the
* file pointer passed in. If the programmer wants to print to the screen,
* he/she will pass in stdout.
*/
void printList(linkedlist *llist,FILE *fp)
{
node *n;
friend *f;
// for each node, print out the friend attached to it
for(n = llist->head; n != NULL ; n = llist->head->next)
{
// assign f to the friend of the right node
f = n->value;
// print the friend out
fprintf(fp,"%s %s: %s\n",
f->firstname, f->lastname, f->birthdate);
}
}
Thank You
The for loop in printList isn't quite right:
for(n = llist->head; n != NULL ; n = llist->head->next)
This should read:
for(n = llist->head; n != NULL ; n = n->next)
Otherwise from the second iteration onwards, n gets set to the same value every single time.
The following isn't related to the problem you're having, but I thought I'd mention it anyway. In the following code:
if (llist == NULL)
{
// this link is the entire list
llist->head = n;
printf("adding friend to null list\n");
}
if llist == NULL, the llist->head = n will segfault.
With the current signature of addHead(), there's not a lot you can do if llist is NULL (other than printing an error message and bailing out).
If instead you meant to check whether llist->head is NULL, you don't need to do that since the else block already handles that correctly.
Try:
void printList(linkedlist *llist,FILE *fp)
{
node *n;
friend *f;
// for each node, print out the friend attached to it
for(n = llist->head; n != NULL ; n = n->next)
{
// assign f to the friend of the right node
f = n->value;
// print the friend out
fprintf(fp,"%s %s: %s\n",
f->firstname, f->lastname, f->birthdate);
}
}
I have done the following to your program:
slightly modified the friend structure. Declared firstname and lastname as arrays for convenience.
Wrote a main() which calls other functions
error checking in addHead()
added create_friend() function which creates friend struct
added freeList() to release the memory which was malloc()'ed
corrected looping error in your print function
So here it goes..
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _friend {
char firstname[10];
char lastname[10];
char birthdate[9];
} friend;
typedef struct _node {
friend *value;
struct _node *next;
} node;
typedef struct _linkedlist {
node *head;
} linkedlist;
void addHead(linkedlist *llist, friend *f)
{
node *n = NULL;
if (( n = (node *)malloc(sizeof(node))) == NULL) {
printf("unable to allocate memory \n");
exit(1);
}
n->value = f;
n->next = NULL;
if (llist == NULL) {
llist->head = n;
printf("adding friend to null list\n");
} else {
n->next = llist->head;
printf("adding %s to head\n", n->value->firstname);
llist->head = n;
}
return;
}
void printList(linkedlist *llist)
{
node *n;
friend *f;
if (llist->head == NULL) {
printf("Empty list \n");
return;
}
for(n = llist->head; n != NULL ; n = n->next) {
f = n->value;
printf("%s %s %d \n", f->firstname, f->lastname, f->birthdate);
}
return;
}
friend * create_friend(char *fn, char *ln, char *dob)
{
friend *fp = NULL;
if ((fp = malloc(sizeof(friend))) == NULL) {
printf("unable to allocate memory \n");
exit(1);
}
strcpy(fp->firstname, fn);
strcpy(fp->lastname, ln);
strcpy(fp->birthdate, dob);
return fp;
}
void freeList(linkedlist *llist)
{
node *cur = llist->head;
node *prev = cur;
friend *f;
while (cur != NULL) {
prev = cur;
cur = cur->next;
f = prev->value;
printf("freeing .. %s %s %d \n", f->firstname, f->lastname, f->birthdate);
free(prev->value);
free(prev);
}
return;
}
int main(void)
{
linkedlist ll;
friend *f;
ll.head = NULL;
f = create_friend("firstname1", "lastname1", "12345678");
addHead(&ll, f);
f = create_friend("firstname2", "lastname2", "12345678");
addHead(&ll, f);
f = create_friend("firstname3", "lastname3", "12345678");
addHead(&ll, f);
printList(&ll);
freeList(&ll);
ll.head = NULL;
printList(&ll);
return 0;
}
Hope this helps!
Should be n = n ->next otherwise you're just getting the next of the head every time.

Resources