Reputation: 13
I made a doubly link list and ran it a couple times with functions to add nodes at end, output the length of the list and to print all the elements.
It was working fine.
Then I made a function to add a node at a specific location called AddNodeAt()
. and since then, it no longer works.
head
keeps getting set to NULL
.
After AddNode()
is done the other functions work as if head
points to NULL
instead of the list.
This is the full code:
#include <stdio.h>
#include <stdlib.h>
struct node {
node *prev;
int val;
node *next;
};
typedef struct node node;
node *head;
node *AddNode(node *head, int value)
{
node *ptr = (node *)malloc(sizeof(node));
if (!ptr) {
printf("No Memory Available");
} else
if (!head) {
ptr->val = value;
ptr->next = NULL;
ptr->prev = NULL;
head = ptr;
} else {
node *temp = head;
while (temp->next) {
temp = temp->next;
}
temp->next = ptr;
ptr->prev = temp;
ptr->next = NULL;
ptr->val = value;
}
return head;
}
int ListLength(node *head)
{
int count = 0;
if (head == NULL) {
printf("\nEmpty List\n");
} else {
node *temp = head;
count = 1;
while (temp->next != NULL) {
temp = temp->next;
count++;
}
printf("\n%d nodes\n", count);
}
return count;
}
node *AddNodeAt(node *head, int position, int value)
{
int i = 0;
node *temp = head;
node *ptr = (node *)malloc(sizeof(node));
if (head == NULL && position != 1) {
printf("Empty Linklist, cannot insert node at the given position");
} else
if (position > ListLength(head) + 1) {
printf("list too short, cannot insert node at the given position");
} else
if (position == ListLength(head) + 1) {
while (temp->next) {
temp = temp->next;
}
temp->next = ptr;
ptr->next = NULL;
ptr->val = value;
ptr->prev = temp;
} else {
while (i < position) {
i++;
temp = temp->next;
}
ptr->next = temp->next;
temp->next = ptr;
ptr->prev = temp;
ptr->val = value;
temp = ptr->next;
temp->prev = ptr;
}
return head;
}
void PrintList(node *head)
{
node *temp = head;
if (!head) {
printf("list empty");
} else {
while (temp->next != NULL) {
printf("%d->", temp->val);
temp = temp->next;
}
printf("%d", temp->val);
}
}
int main() {
int value = 0;
int num = 0;
int position = 0;
printf("Number of nodes to be made: ");
scanf("%d", &num);
for (int i = 1; i <= num; i++) {
printf("value in node number %d: ", i);
scanf("%d", &value);
AddNode(head, value);
}
PrintList(head);
ListLength(head);
printf("\nPosition of new node: ");
scanf("%d", &position);
printf("\nNumber of nodes:");
scanf("%d", &value);
AddNodeAt(head, position, value);
PrintList(head);
ListLength(head);
return 0;
}
Any guidance would be appreciated. I tried commenting out the sections which I added right before this issue occurred.
I expected others to start working as they were working before, but they didn't. head
keeps getting set to NULL
.
Upvotes: 1
Views: 134
Reputation: 1765
As written AddNode
is wrong, or at least used wrong. In main
, as provided, AddNode
is called twice:
for (int i = 1; i <= num; i++)
{
printf("value in node nummber %d : ", i);
scanf("%d", &value);
AddNode(head, value);
}
PrintList(head);
ListLength(head);
printf("\nPosition of new node:");
scanf("%d", &position);
printf("\nNumber of node :");
scanf("%d", &value);
AddNodeAt(head, position, value);
And the return value is ignored. If you change it to
for (int i = 1; i <= num; i++)
{
printf("value in node nummber %d : ", i);
scanf("%d", &value);
head = AddNode(head, value);
}
PrintList(head);
ListLength(head);
printf("\nPosition of new node:");
scanf("%d", &position);
printf("\nNumber of node :");
scanf("%d", &value);
head = AddNodeAt(head, position, value);
It will work. But there are other bugs.
Also you need to change
struct node
{
node* prev;
int val;
node* next;
};
to
struct node
{
struct node* prev;
int val;
struct node* next;
};
To compile this in C
, or at least place the typedef
before the struct
declaration, as
typedef struct node node;
struct node
{
node* prev;
int val;
node* next;
};
I will not go deep into the bugs. Instead I will provide some discussion and add a complete example (and some more discussion) at the end. It is a long post and you can jump to TL;DR or just ignore all this...
AddNode()
Inside AddNode
head
is a local node*
, but just above we see node
as a global node*
thing. Not good at all. And in main
the return value is just ignored.
node* head;
node* AddNode(node* head, int value)
{
node* ptr = (node*)malloc(sizeof(node));
if (!ptr)
{
printf("No Memory Available");
}
else if (!head)
{
ptr->val = value;
ptr->next = NULL;
ptr->prev = NULL;
head = ptr;
}
else
{
node* temp = head;
while (temp->next)
{
temp = temp->next;
}
temp->next = ptr;
ptr->prev = temp;
ptr->next = NULL;
ptr->val = value;
}
return head;
}
You could just delete this argument, or just start using the return value to update the head of the list.
node* AddNodeAt(node* head, int position, int value)
This one also has bugs.
As an example if this condition is true:
node* ptr = (node*)malloc(sizeof(node));
if (head == NULL && position != 1)
{
printf(
"Empty Linklist,cant insert node at the "
"given position");
}
the function will print the message and return head
unchanged. But the allocated memory in ptr
is gone for good...
Also it does not work is position
is 1
, where it should add the node at the head.
Anyway, since the value returned from the function is just ignored in main
there is no future for the list anyway.
main
should be the first function in the code file. Or if possible in a separate file. This way you can write many small test programs and test everything faster.scanf
returns and int
for a reason. read the manual. Tes the return value against the number of expected items. scanf
is --- hence the name --- a scanner, and it is normal to read nothing. As for your program... Just enter e
insted of 4
just above and boom: there goes your program.head
in your case. It is a disaster. Use arguments.linked lists are containers. All lists are equal: just a --- possibly empty --- sequence of nodes. Not data, just nodes. Each node contains (your case) or points to a single unit of data, let us name it a record. So operations on the list does not depend on what is being listed at he moment. Or should not. This way your code can be reused for the next classical exercise, like the list of movie tickes, the music playlist, the library booklist, the list for parking lot management :D and all the other usual suspects.
list
in the provided codetypedef struct node node;
struct node
{
node* prev;
int val;
node* next;
};
node* head;
This is just a node and a global pointer to a node. There is not even a mention to a list.
list
alternative// this is a node
typedef struct st_node
{
Info* info;
struct st_node* prev; // links
struct st_node* next;
} Node;
// this is a list
typedef struct
{
size_t size;
Node* head;
Node* tail;
} List;
Now we have a linked list. And the list has metadata: the minimum expected: pointers to head and tail and a size counter. And you see that life can be easier: each List
has its own head
, tail
and size
thing.
What about the node? Each node has the links and a pointer to some Info
thing. These way you can have lists of anything: the data itself is not even mentioned in the node except for the name.
You can declare
List one;
List other = { 0, NULL, NULL };
List* set[30];
and have lists one
and other
and an array of 30 pointers to lists from set[0]
to set[29]
.
List
operations
List* so_create_list(void);
List* so_delete_list(List*);
int so_insert(Info*, List*, int (*compare)(void*, void*));
int so_insert_at(int position, Info* value, List* list);
int so_insert_back(Info*, List*);
int so_insert_front(Info*, List*);
int so_print_list(FILE*,List*,const char*);
int so_sort_nodes(List*, int (*compare)(void*, void*));
Writing this way we see that nodes are internal to the list, not present in any argument list. We use only pointers to List
and Info
so if the list changes or even if Info
changes completely, from the int
in this example to a complex dynamically allocated multi-level struct, it will make no difference for the list itself.
In fact if each node contains a pointer to a data record, all the list need to know is how to
C++
for exampleC++
.toString
method in java.C
's qsort
function.If we provide this to the list it can be a list of anything. Generic and useful. I will not implement it now, but I hope you can get the idea from the code: it is just a matter of writing these node operations as functions and using them in the proper places.
insert_at(int position, int value, List* list);
This function is seen mostly in student's tasks. Makes not much sense access data in linked lists by position. If this is important we probably would be using arrays or hash tables. Linked Lists are built for navegation, well, by links.
Anyway, a possible implementation is in the example code, alog with some use cases.
Using an int
inside the node as the data, an example follows
list.h
: list functions for the example#include <stdio.h>
#include <stdlib.h>
// these are operations on data
int so_cmp_info(void* a, void* b);
int so_print_info(int, const char*);
// this is a node
typedef struct st_node
{
int info;
struct st_node* prev; // links
struct st_node* next;
} Node;
// this is a list
typedef struct
{
size_t size;
Node* head;
Node* tail;
} List;
// operations on List
List* so_create_list(void);
List* so_delete_list(List*);
int so_insert(int, List*, int (*compare)(void*, void*));
int so_insert_at(int position, int value, List* list);
int so_insert_back(int, List*);
int so_insert_front(int, List*);
int so_print_list(List*, const char*);
int so_print_list_r(List*, const char*);
int so_sort_nodes(List*, int (*compare)(void*, void*));
As so_insert_at()
is not a common operation for linked lists, so_sort_nodes()
is also not a common thing. It is here just to show that all we need to sort is:
The presence of the comparison function for 2 records makes it easy to write
int so_insert(int, List*,int (*compare)(void*, void*));
to insert records in some determined order, like ISBN for a book list, or song duration for the playlists. We can have many compare functions with different criteria. If we change the criteria it is needed to sort the list using the new criteria before inserting using the new comparison function, and this is the reason for the sort function.
A possible implementation for so_insert
is in the example.
A few examples:
List* so_create_list(void)
{
List* list = malloc(sizeof(List));
if (list == NULL) return NULL;
list->head = NULL;
list->tail = NULL;
list->size = 0;
fprintf(stderr, "list created\n");
return list;
}
This is a possible way to create a list. Using it is as simple as in the example:
List* list = so_create_list();
NULL
is returned in case of error.
// inserts 'info' at the tail of the list
int so_insert_back(int info, List* list)
{
if (list == NULL) return -1; // no list
Node* node = (Node*)malloc(sizeof(Node));
if (node == NULL) return -2; // no alloc
// copy the record pointed by 'info'
node->info = info;
if (list->size == 0) // first node
{
node->next = NULL;
node->prev = NULL;
list->size = 1;
list->head = node;
list->tail = node;
return 0; // 1st node
};
node->next = NULL;
node->prev = list->tail;
list->tail->next = node;
list->tail = node;
list->size += 1;
return 0;
}
This is a simple implementaton for insert_back()
that inserts a record at the end of the list. insert_front()
is similar, since the list keeps pointers for head and tail.
List* list = so_create_list();
if (list == NULL) return -1;
for (int info = 1; info <= 10; info += 2)
so_insert_back(info, list);
so_print_list(list, "\tinserted 1 to 9 ==>\n\n");
for (int info = -1; info >= -10; info -= 2)
so_insert_front(info, list);
so_print_list(list, "\tinserted -1 to -9 ==>\n\n");
This lines from the example inserts some records at head and tail of the list, and print it. Output is
list created
inserted 1 to 9 ==>
5 data points:
First: 1 Last: 9
1 3 5 7 9
inserted -1 to -9 ==>
10 data points:
First: -9 Last: 9
-9 -7 -5 -3 -1 1 3 5 7 9
And we see the convenience of non-interacive code and of accepting an optional title message in so_print_list()
As an example of ordering, these lines in the example
so_sort_nodes(list, so_cmp_info);
so_print_list(list, "\tsorted descending value ==>\n\n");
are all we need to sort the list in-place in descending order --- based on the compare function anyway.
list.c
an example implementation for these functions#include "List.h"
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
Node* so_locate_at(List* list, size_t pos);
int so_swap_info(Node* one, Node* other);
// list related functions
List* so_create_list(void)
{
List* list = malloc(sizeof(List));
if (list == NULL) return NULL;
list->head = NULL;
list->tail = NULL;
list->size = 0;
fprintf(stderr, "list created\n");
return list;
}
List* so_delete_list(List* del)
{
if (del == NULL) return NULL; // no list
Node* save = NULL;
for (size_t i = 0; i < del->size; i += 1)
{ // delete nodes, 1 by 1
save = del->head->next;
// delete the record pointed by 'head'
free(del->head);
del->head = save;
};
free(del); // delete list
fprintf(stderr, "list deleted\n");
return NULL;
}
int so_insert(
int value, List* list, int (*cmp)(void*, void*))
{
if (list == NULL) return -1; // no list
Node* p = list->head;
for (size_t i = 0; i < list->size; i += 1)
{ // cmp() > 0 marks the insertion point
if (cmp(&value, &p->info) > 0)
{
Node* node = (Node*)malloc(sizeof(Node));
if (node == NULL) return -4; // no alloc
node->info = value;
// link the new node before 'p'
if (p == list->head)
return so_insert_front(value, list);
p->prev->next = node;
node->next = p;
node->prev = p->prev;
p->prev = node;
// update size
list->size += 1;
return 0;
}
p = p->next;
}
// all nodes ordered. insert at the end
return so_insert_back(value, list);
}
// inserts 'val' at 'position' in 'List'
// first position is 1
int so_insert_at(int position, int val, List* list)
{
if (list == NULL) return -1;
// insert at head?
if (position == 1) return so_insert_front(val, list);
if (list->size == 0) return -2; // empty list
if (position > list->size) return -3;
if (position == list->size)
return so_insert_back(val, list);
// ok: just advance pointer 'position'-1 times
Node* p = list->head;
for (int i = 1; i < position; i += 1) p = p->next;
Node* node = (Node*)malloc(sizeof(Node));
if (node == NULL) return -4; // no alloc
node->info = val;
// link the new node before 'p'
p->prev->next = node;
node->next = p;
node->prev = p->prev;
p->prev = node;
// update size
list->size += 1;
return 0;
}
// inserts 'info' at the tail of the list
int so_insert_back(int info, List* list)
{
if (list == NULL) return -1; // no list
Node* node = (Node*)malloc(sizeof(Node));
if (node == NULL) return -2; // no alloc
// copy the record pointed by 'info'
node->info = info;
if (list->size == 0) // first node
{
node->next = NULL;
node->prev = NULL;
list->size = 1;
list->head = node;
list->tail = node;
return 0; // 1st node
};
node->next = NULL;
node->prev = list->tail;
list->tail->next = node;
list->tail = node;
list->size += 1;
return 0;
}
// inserts 'info' at the head of the list
int so_insert_front(int info, List* list)
{
if (list == NULL) return -1; // no list
Node* node = (Node*)malloc(sizeof(Node));
if (node == NULL) return -2; // no alloc
// copy the record pointed by 'info'
node->info = info;
if (list->size == 0)
{
node->next = NULL;
node->prev = NULL;
list->size = 1;
list->head = node;
list->tail = node;
return 0; // 1st node
};
node->next = list->head;
node->prev = NULL;
list->head->prev = node;
list->head = node;
list->size += 1;
return 0;
}
int so_print_list(List* list, const char* msg)
{
FILE* out = stdout;
if (list == NULL)
{
fprintf(out, "No valid list!\n");
return 0;
}
if (list->size == 0)
{
fprintf(out, "list is empty\n");
return 0;
}
if (msg != NULL)
printf(
"\n%s%zd data points:\nFirst: %d Last: %d\n",
msg, list->size, list->head->info,
list->tail->info);
else
printf(
"\n%zd data points:\nFirst: %d Last: %d\n",
list->size, list->head->info, list->tail->info);
Node* p = list->head;
for (size_t i = 0; i < list->size; i += 1)
{
so_print_info(p->info, NULL);
p = p->next;
}
printf("\n\n");
return 0;
}
int so_print_list_r(List* list, const char* msg)
{
FILE* out = stdout;
if (list == NULL)
{
fprintf(out, "No valid list!\n");
return 0;
}
if (list->size == 0)
{
fprintf(out, "list is empty\n");
return 0;
}
if (msg != NULL)
printf(
"\n%s%zd data points (reverse order):\nFirst: "
"%d Last: %d\n",
msg, list->size, list->head->info,
list->tail->info);
else
printf(
"\n%zd data points (reverse order):\nFirst: %d "
" Last: %d\n",
list->size, list->head->info, list->tail->info);
Node* p = list->tail;
for (size_t i = 0; i < list->size; i += 1)
{
so_print_info(p->info, NULL);
p = p->prev;
}
printf("\n[-----]\n\n");
return 0;
}
// return a pointer to a copy of the record
// at such 'pos', or 'NULL'. 'pos'starts at 0
Node* so_locate_at(List* list, size_t pos)
{
if (list == NULL) return NULL;
if (list->size < 1 + pos) return NULL;
Node* nd = list->head;
for (size_t i = 0; i < pos; i += 1) nd = nd->next;
return nd;
}
int so_sort_nodes(List* list, int (*cmp)(void*, void*))
{
if (list == NULL) return -1;
if (list->size < 2) return -2;
if (cmp == NULL) return -3;
for (int i = 0; i < list->size - 1; i += 1)
for (int j = 0; j < list->size - i - 1; j += 1)
{
Node* one = so_locate_at(list, j);
if (cmp((void*)one, (void*)one->next) < 0)
so_swap_info(one, one->next);
}
return 0;
}
// swap data from these 2 nodes
int so_swap_info(Node* one, Node* other)
{
if (one == NULL) return -1;
if (other == NULL) return -1;
int temp = one->info;
one->info = other->info;
other->info = temp;
return 0;
}
int so_cmp_info(void* a, void* b)
{
if (a == NULL) return 0;
if (b == NULL) return 0;
int ta = ((Node*)a)->info;
int tb = ((Node*)b)->info;
if (ta > tb) return +1;
if (ta < tb) return -1;
return 0;
};
int so_print_info(int info, const char* msg)
{
if (msg != NULL) printf("%s", msg);
printf("%4d ", info);
return 0;
}
main
for the exampleThis code creates a list and tests some of the functions. The list is printed at each step. At the end the list is sorted, displayed and deleted.
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main(void)
{
List* list = so_create_list();
if (list == NULL) return -1;
for (int info = 1; info <= 10; info += 2)
so_insert_back(info, list);
so_print_list(list, "\tinserted 1 to 9 ==>\n\n");
for (int info = -1; info >= -10; info -= 2)
so_insert_front(info, list);
so_print_list(list, "\tinserted -1 to -9 ==>\n\n");
// insert at the tail using so_insert_at()
so_insert_at((int)list->size, 10, list);
so_insert_at((int)list->size, 11, list);
so_print_list(
list, "\tinserted 10 & 11 at the end ==>\n\n");
// inser at head using so_insert_at()
so_insert_at(1, -10, list);
so_insert_at(1, -11, list);
so_print_list(
list, "\tinserted -10 & -11 at the head ==>\n\n");
so_insert_at(9,2, list);
so_print_list(list, "\tinserted 2 at pos 9 ==>\n\n");
so_insert_at(11,4, list);
so_print_list(list, "\tinserted 4 at pos 11 ==>\n\n");
so_insert_at(13,6, list);
so_print_list(list, "\tinserted 6 at pos 13 ==>\n\n");
so_sort_nodes(list, so_cmp_info);
so_print_list(list, "\tsorted descending value ==>\n\n");
so_delete_list(list);
return 0;
}
list created
inserted 1 to 9 ==>
5 data points:
First: 1 Last: 9
1 3 5 7 9
inserted -1 to -9 ==>
10 data points:
First: -9 Last: 9
-9 -7 -5 -3 -1 1 3 5 7 9
inserted 10 & 11 at the end ==>
12 data points:
First: -9 Last: 11
-9 -7 -5 -3 -1 1 3 5 7 9 10 11
inserted -10 & -11 at the head ==>
14 data points:
First: -11 Last: 11
-11 -10 -9 -7 -5 -3 -1 1 3 5 7 9 10 11
inserted 2 at pos 9 ==>
15 data points:
First: -11 Last: 11
-11 -10 -9 -7 -5 -3 -1 1 2 3 5 7 9 10 11
inserted 4 at pos 11 ==>
16 data points:
First: -11 Last: 11
-11 -10 -9 -7 -5 -3 -1 1 2 3 4 5 7 9 10 11
inserted 6 at pos 13 ==>
17 data points:
First: -11 Last: 11
-11 -10 -9 -7 -5 -3 -1 1 2 3 4 5 6 7 9 10 11
sorted descending value ==>
17 data points:
First: 11 Last: -11
11 10 9 7 6 5 4 3 2 1 -1 -3 -5 -7 -9 -10 -11
list deleted
This small example shows how to insert data ordered by some criteria:
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main(void)
{
srand(240605);
List* list = so_create_list();
if (list == NULL) return -1;
for (int i = 0; i < 20; i += 1)
so_insert(rand()%100, list, so_cmp_info);
so_print_list(list, "\tinserted 20 elements with values from [0..99] ==>\n");
// force insert at the end
so_insert(1000, list, so_cmp_info);
so_print_list(list, "\tinserted 1000 ==>\n");
// force insert at the head
so_insert(-1000, list, so_cmp_info);
so_print_list(list, "\tinserted -1000 ==>\n");
so_delete_list(list);
return 0;
}
list created
inserted 20 elements with values from [0..99] ==>
20 data points:
First: 99 Last: 3
99 94 91 89 86 85 84 83 79 79 72 62 61 42 37 36 35 22 12 3
inserted 1000 ==>
21 data points:
First: 1000 Last: 3
1000 99 94 91 89 86 85 84 83 79 79 72 62 61 42 37 36 35 22 12 3
inserted -1000 ==>
22 data points:
First: 1000 Last: -1000
1000 99 94 91 89 86 85 84 83 79 79 72 62 61 42 37 36 35 22 12 3 -1000
list deleted
It is a bit off-topic, here only for completeness
Upvotes: 0
Reputation: 145277
head
does not get set to NULL
: the global variable head
is initialized to NULL
before the program starts and is never updated to point to the allocated list.
You should make head
a local variable in main
and update it to the return value of functions AddNode
and AddNodeAt
.
Note these other problems:
scanf()
and report input errors.typedef
before the struct node
definition so node
is available for the member definitions. As posted, your code does not compile as C, but is valid C++.ListLength
should not output anything. Use separate functions to compute the list length and to print the list length.#include <stdio.h>
#include <stdlib.h>
typedef struct node node;
struct node {
node *prev;
int val;
node *next;
};
int get_integer(void) {
for (;;) {
int value;
int c;
switch (scanf("%d", &value)) {
case 1:
/* read and discard the rest of the input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
printf("\n");
return value;
case EOF:
fprintf(stderr, "unexpected end of file, aborting\n");
exit(1);
default:
/* read and discard the rest of the input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
fprintf(stderr, "invalid input, try again\n");
break;
}
}
}
node *AddNode(node *head, int value) {
node *ptr = (node *)malloc(sizeof(node));
if (!ptr) {
fprintf(stderr, "No Memory Available\n");
exit(1);
}
ptr->val = value;
ptr->next = NULL;
ptr->prev = NULL;
if (!head) {
head = ptr;
} else {
node *temp = head;
while (temp->next) {
temp = temp->next;
}
temp->next = ptr;
ptr->prev = temp;
}
return head;
}
int ListLength(const node *head) {
int count = 0;
while (head != NULL) {
count++;
head = head->next;
}
return count;
}
void PrintListLength(const node *head) {
if (head == NULL) {
printf("Empty List\n");
} else {
printf("%d nodes\n", ListLength(head));
}
}
node *AddNodeAt(node *head, int position, int value) {
if (position > ListLength(head) + 1) {
printf("list too short, cannot insert node at the given position\n");
return head;
}
node *ptr = (node *)malloc(sizeof(node));
if (!ptr) {
fprintf(stderr, "No Memory Available\n");
exit(1);
}
/* initialize the new node */
ptr->value = value;
ptr->next = NULL;
ptr->prev = NULL;
if (position <= 1) {
/* insert at front */
if (head) {
ptr->next = head;
head->prev = ptr;
}
head = ptr;
} else {
node *temp = head;
for (int i = 1; i < position; i++) {
temp = temp->next;
i++;
}
ptr->prev = temp;
temp->next = ptr;
ptr->next = temp->next;
if (ptr->next) {
ptr->next->prev = ptr;
}
}
return head;
}
void PrintList(const node *head) {
const node *temp = head;
if (!head) {
printf("list empty\n");
} else {
while (temp->next != NULL) {
printf("%d->", temp->val);
temp = temp->next;
}
printf("%d\n", temp->val);
}
}
void FreeList(node *head) {
while (head) {
node *next = head->next;
free(head);
head = next;
}
}
int main(void) {
int value = 0;
int num = 0;
int position = 0;
node *head = NULL;
printf("Number of nodes to be made: ");
num = get_integer();
for (int i = 1; i <= num; i++) {
printf("value in node number %d: ", i);
value = get_integer();
head = AddNode(head, value);
}
PrintList(head);
PrintListLength(head);
printf("Position of new node: ");
position = get_integer();
printf("Node value: ");
value = get_integer();
head = AddNodeAt(head, position, value);
PrintList(head);
PrintListLength(head);
FreeList(head);
return 0;
}
Upvotes: 0
Reputation: 409422
The problem is the assignment head=ptr
in the AddNode
function. That will only modify the local variable head
. It will not modify the global variable of the same name, that global variable will stay NULL
.
The simple solution to this is to use the pointer that AddNode
returns:
head = AddNode(head,value);
You have the same problem with the AddNodeAt
function.
On a related note, please don't use global variables. You could define head
locally inside the main
function.
Upvotes: 3