I have this code through which it inserts node at the starting.This code also contains a function which prints linked list and if empty it prints linked list is empty .
when i run this code , i have my ouput as Linked list is empty .
struct node {
int data;
node* next;
}* start = NULL;
void append(node* linkedlist, int data)
{
node* new_element = NULL;
new_element = (node*)malloc(sizeof(struct node));
new_element->data = data;
if (linkedlist == NULL) {
linkedlist = new_element;
new_element->next = NULL;
}
else {
new_element->next = (linkedlist)->next;
(linkedlist)->next = new_element;
}
}
int main()
{
append(start, 4);
append(start, 5);
printList(start);
}
Update:
void printList(node* linkedlist)
{
node* ptr = linkedlist;
if (linkedlist == NULL) {
printf("Linked list is empty");
exit(0);
}
else {
while (ptr != NULL) {
cout << ptr->data;
ptr = ptr->next;
}
}
}
What could i be possibly doing wrong? What should i change in order to make it work?
Your problem is here linkedlist = new_element; When passing arguments to a function they are passed by value. Even when you pass a pointer you are actually passing a copy of that pointer(you can verify by printing the address of linkedlist inside the function and outside the function). The statement linkedlist = new_element; assigns the new_element to a copy. Once the function return you end up with nothing (and a memory leak). Remember when you need to change a pointer itself you must use a double pointer **
You put in the value of start which points to null. Then you copy it to another pointer linkedlist and set it to a new value. After the function start is still pointing to null though because you never changed the value of start.
You could try to change your declaration to
void append(node *&linkedlist,int data)
If you are using a c++ compiler.
else
void append(node **linkedlist,int data)
...
append(&start,4);
if you are using C
For starters the code you showed is not valid C code. You are using C++ elements. So the program will not even compile as a C program.
As the node start that is initially set to NULL can be changed by the function you have to pass it by reference. Otherwise the function parameter linkedlist is a local variable of the function that will be changed in the function and at last will be destroyed after exiting the function. So the original pointer start itself will not be changed.
Also this else code block
else {
new_element->next = (linkedlist)->next;
(linkedlist)->next = new_element;
}
is wrong. This code block does not insert a new node in the beginning of the list. It inserts a new node after the first already existent node.
Take into account that the function name append is not suitable for inserting a node in the beginning of the list. It would be better to name it like insert.
The function can look the following way
int insert( struct node **linkedlist, int data )
{
struct node *new_element = malloc( sizeof( struct node ) );
int success = new_element != NULL;
if ( success )
{
new_element->data = data;
new_element->next = *linkedlist;
*linkedlist = new_element;
}
return success;
}
If you indeed need a function that appends nodes to the list then it can look the following way
int append( struct node **linkedlist, int data )
{
struct node *new_element = malloc( sizeof( struct node ) );
int success = new_element != NULL;
if ( success )
{
new_element->data = data;
new_element->next = NULL;
while ( *linkedlist != NULL ) linkedlist = &( *linkedlist )->next;
*linkedlist = new_element;
}
return success;
}
Here is a demonstrative program
#include <stdlib.h>
#include <stdio.h>
struct node
{
int data;
struct node* next;
} *start = NULL;
int insert( struct node **linkedlist, int data )
{
struct node *new_element = malloc( sizeof( struct node ) );
int success = new_element != NULL;
if ( success )
{
new_element->data = data;
new_element->next = *linkedlist;
*linkedlist = new_element;
}
return success;
}
int append( struct node **linkedlist, int data )
{
struct node *new_element = malloc( sizeof( struct node ) );
int success = new_element != NULL;
if ( success )
{
new_element->data = data;
new_element->next = NULL;
while ( *linkedlist != NULL ) linkedlist = &( *linkedlist )->next;
*linkedlist = new_element;
}
return success;
}
void printList( struct node* linkedlist )
{
if ( linkedlist == NULL )
{
puts( "Linked list is empty" );
}
else
{
for ( struct node *current = linkedlist; current != NULL; current = current->next )
{
printf( "%d ", current->data );
}
printf( "\n" );
}
}
int main( void )
{
const int N = 10;
for ( int i = 1; i <= N; i++ )
{
if ( i % 2 == 0 ) append( &start, i );
else insert( &start, i );
}
printList( start );
return 0;
}
Its output is
9 7 5 3 1 2 4 6 8 10
I dont think your if statement is correct. I would do it like this
if(linkedlist == null)
{
//head node is null i.e, linked list is empty hence make the new node as head node
linkedlist = new_element;
}else{
//make the new node point to the head
new_element->next = linkedlist;
//make the new node as head node
linkedlist = new_element;
}
In the append function you should
First initialise next of newnode to be null
Check before inserting for empty list, if empty then then make this as head.
If it is not empty then make the new node point to the head of your list and make it the new head.
To reflect back the insertion done in append you should return the modified head from the function(Also modify main accordingly).
Look at this code:-
node *append(node *linkedlist,int data){
node *new_element=NULL;
new_element=(node *)malloc(sizeof(struct node));
new_element->data=data;
new_element->next=NULL;// initialise next of newnode to be null here
// In case of empty list make this as first node
if(linkedlist==NULL)
{
linkedlist=new_element;
}
else
{
new_element->next=(linkedlist);//point the new node to head of list
(linkedlist)=new_element;// make new node as head
}
return linkedlist;
}
int main()
{
start = append(start, 4);
start = append(start, 5);
printList(start);
}
When you pass a parameter in C, it creates a local copy for the function to use. When you modify the parameter inside the function, it only changes the local copy.
void f1( int a )
{
a = 1; // modification does not affect the calling function
}
int b=0;
f1( b );
assert( b == 0 ); // b was not changed by f
In C (or C-style C++), if you want a function to modify a parameter, you need to pass it as a pointer:
void f2( int * a )
{
(*a) = 1;
}
int b=0;
f2( &b );
assert( b == 1 ); // b was changed by f
If that parameter was already a pointer type, then you need to pass it as a pointer to a pointer:
void f3( int * * a )
{
(*a) = (int*) malloc(sizeof(int));
(**a) = 1;
}
int * b = NULL;
f3( &b );
assert( b != NULL ); // the pointer was initialized
assert( *b == 1 ); // the pointed-to value was initialized
The assignment process can be a bit simpler in C++ because you can use reference parameters instead of explicitly specifying the pointer.
Related
having segmentation error while trying to access nodes
i can create new nodes with my add function after function executes i cant access my nodes. i think they deallocated in memory but i couldnt figure it out.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *nextNode;
};
struct node *head;
void add(int data)
{
struct node *new = (struct node *)malloc(sizeof(struct node));
new->data = data;
new->nextNode = NULL;
struct node *temp1;
temp1 = head;
while (temp1 != NULL)
{
temp1 = temp1->nextNode;
}
temp1 = new;
printf("\nValue of temp1:%d\nValue of new: %d\n",temp1,new);
printf("\nData of temp1:%d\nData of new:%d\n",temp1->data,new->data);
}
void printList()
{
int i = 1;
struct node *tempP;
tempP = head;
while (tempP != NULL)
{
printf("\nData of %dth element is : %d\n", i, tempP->data);
tempP = tempP->nextNode;
i++;
}
}
void main()
{
head = (struct node *)malloc(sizeof(struct node));
head->data = 10;
head->nextNode = NULL;
add(20);
add(30);
add(40);
printList();
}
This code snippet within the function add
struct node *temp1;
temp1 = head;
while (temp1 != NULL)
{
temp1 = temp1->nextNode;
}
temp1 = new;
is wrong. Within it there is changed the local variable temp1. It is not linked with the list.
Also using the conversion specifier %d to output a pointer invokes undefined behavior. You should use conversion specifier %p.
Using your approach to the function definition you could write instead.
void add(int data)
{
struct node *new = malloc( sizeof( *new ) );
new->data = data;
new->nextNode = NULL;
if ( head == NULL )
{
head = new;
}
else
{
struct node *temp1 = head;
while ( temp1->nextNode != NULL)
{
temp1 = temp1->nextNode;
}
temp1->nextNode = new;
}
printf("\nValue of temp1->nextNode:%p\nValue of new: %p\n",
( void * )temp1->nextNode, ( void * )new);
printf("\nData of temp1->nectNode:%d\nData of new:%d\n",
temp1->nextNode->data,new->data);
}
Pay attention to that it is a bad design when functions depend on a global variable as in your case where the functions depend on the global variable head.
And it is also a bad idea when the first node is added to the list bypassing the function add.
And you need check whether a node was successfully allocated.
Also according to the C Standard the function main without parameters shall be declared like
int main( void )
As for me I would declare the pointer to the head node in main like
int main( void )
{
struct node *head = NULL;
// ...
And the function add will look like
int add( struct node **head, int data )
{
struct node *new_node = malloc( sizeof( *new_node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->nextNode = NULL;
while ( *head != NULL ) head = &( *head )->nextNode;
*head = new_node;
}
return success;
}
and called like
struct node *head = NULL;
add( &head, 10 );
add( &head, 20 );
add( &head, 30 );
add( &head, 40 );
In turn the function printList can look like
void printList( const struct node *head )
{
for ( size_t i = 1; head != NULL; head = head->nextNode )
{
printf( "Data of %zuth element is : %d\n", i++, head->data);
}
}
And you need at least to write one more function that will free all the allocated memory.
There were a handful of mistakes in your add() function, which I've highlighted and fixed below:
void add(int data)
{
struct node *new = malloc(sizeof(*new)); // suggested by ryyker
new->data = data;
new->nextNode = NULL;
struct node *temp1 = head; // just keep it short
while (temp1->nextNode != NULL) // temp1 != NULL will always result in it being NULL, last node is the node with NULL as next
{
temp1 = temp1->nextNode;
}
temp1->nextNode = new; // you want the next in the list to be the new node, not reassign the head to a new node. That's a memory leak.
// remember: temp1 == head, and head = new makes head lose the original node and point to the newly created one
printf("\nValue of temp1:%p\nValue of new: %p\n",temp1,new); // %p for pointers
printf("\nData of temp1:%d\nData of new:%d\n",temp1->data,new->data);
}
Output:
Value of temp1:0x55809a4b22a0
Value of new: 0x55809a4b22c0
Data of temp1:10
Data of new:20
Value of temp1:0x55809a4b22c0
Value of new: 0x55809a4b26f0
Data of temp1:20
Data of new:30
Value of temp1:0x55809a4b26f0
Value of new: 0x55809a4b2710
Data of temp1:30
Data of new:40
Data of 1th element is : 10
Data of 2th element is : 20
Data of 3th element is : 30
Data of 4th element is : 40
I am practicing linked list structure while learning pointers and I have problem with appending item in list. Here is my code
#include <stdio.h>
#include <stdlib.h>
typedef struct node node_t;
struct node {
int data;
node_t* next;
};
void append(node_t *head, int data) {
if (head == NULL) {
node_t *node = (node_t*)malloc(sizeof(node_t*));
node->data = data;
node->next = NULL;
head = node;
} else {
node_t *node = (node_t*)malloc(sizeof(node_t*));
node->data = data;
node->next = NULL;
if (head->next == NULL) {
head->next = node;
} else {
node_t *current = head;
while (1) {
if (current->next == NULL) {
current->next = node;
break;
}
current = current->next;
}
}
}
}
int main(void) {
node_t *head = NULL;
append(head, 4);
append(head, 6);
printList(head);
return 0;
}
My code breaks when I do head = node; It doesn't change value of head in main. I think I'm missing something but not sure what.
Thank you in advance
You are passing the pointer head by value in the function append. So the function deals with a copy of the passed to it pointer. Changing the copy does not influence on the original pointer. Either pass it by reference or return updated head from the function.
The first approach is much better.
The function can look the following way
int append( node_t **head, int data )
{
node_t *node = malloc( sizeof( node_t ) );
int success = node != NULL;
if ( success )
{
node->data = data;
node->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = node;
}
return success;
}
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
typedef struct node node_t;
struct node
{
int data;
node_t *next;
};
int append( node_t **head, int data )
{
node_t *node = malloc( sizeof( node_t ) );
int success = node != NULL;
if ( success )
{
node->data = data;
node->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = node;
}
return success;
}
void printList( node_t *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->data );
}
puts( "null" );
}
int main(void)
{
node_t *head = NULL;
const int N = 10;
for ( int i = 0; i < N; i++ )
{
append( &head, i );
}
printList( head );
return 0;
}
Its output is
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
It seems the problem is you are passing the head pointer by value, so when you change it inside append(), you're only changing a local variable in that function - as opposed to the head variable within main().
This may be a bit confusing - if you pass a pointer, how can you be passing by value? Well, you might want to have a look at this question:
Is passing pointer argument, pass by value in C++?
... and the bottom line is that append() needs to take a node_t** head, and you'll call it from main with append(&head, 4);. See it working on Coliru.
Also you're allocating sizeof(node_t*) per node. You should be allocating sizeof(node_t).
It doesn't change value of head in main
Nor should it! If the value of head in main changed when you call append(), then your call to printList() would only print the last node in the list, and you'd have no way to refer to the other nodes in the list.
The reason that head isn't changed has been well explained in other answers, i.e. you're passing the head pointer by value. It's important to understand that the head in main() and the head parameter in append() are entirely different variables.
You pass the head of the list by value, so the append function cannot update the pointer in the caller's space, that happens to have the same name head. The head argument in append is a separate variable from the head local variable in main.
You should either pass a pointer to the head node so append can modify it:
void append(node_t **headp, int data) { ...
Or return the possibly modified head node to the caller which will store it back to its own variable:
node_t *append(node_t *head, int data) { ...
In both cases, it is advisable to signal memory allocation failure to the caller. Returning an error code in the first approach is easy, while returning a null pointer in the second approach can work, as long as the caller does not store the return value directly into its head variable, as in case of failure the previous value would be lost.
Here is a modified version with the first approach:
#include <stdio.h>
#include <stdlib.h>
typedef struct node node_t;
struct node {
int data;
node_t *next;
};
// append a new node to the list, return 0 for success, -1 for allocation failure
int append(node_t **headp, int data) {
node_t *node = (node_t *)malloc(sizeof(node_t *));
if (node == NULL)
return -1;
node->data = data;
node->next = NULL;
if (*headp == NULL) {
*headp = node;
} else {
node_t *current = *headp;
while (current->next != NULL) {
current = current->next;
}
current->next = node;
}
return 0;
}
int main(void) {
node_t *head = NULL;
if (append(&head, 4) || append(&head, 6))
printf("node allocation error\n");
printList(head);
// should free the list
return 0;
}
I want to craete a single linked list without gloabal variables. I initialized the first element with NULL and then wanted to copy the first element node to list_. It is copied in the function but the side effect isnĀ“t working. In my main-function the value is still NULL.
If I return the struct in the add_element()function all works fine but, is it possible that l gets the value of node without changing the functions structure and the struct itself?
#include <stdio.h>
#include <stdlib.h>
struct list {
int value;
struct list *next;
};
struct list *initialize(void)
{
struct list * l = NULL;
return l;
}
int add_element(struct list *list_, void *v)
{
struct list *node = malloc(sizeof(struct list));
node->value = *((int*)v);
node->next = NULL;
if(list_ == NULL)
{
list_ = node;
printf("list_->value = %d\n", list_->value); // correct copy
return 0;
}
//TODO if not first then add at end..
return 0;
}
int main()
{
struct list *l = initialize(); // l = NULL
int i = 10;
add_element(l,&i);
if(l == NULL) printf("l == NULL!\n");
printf("l->value = %d\n", l->value); // does not work, l is NULL
return 0;
}
kaylum's comment points you in the right direction.
When you pass a pointer in C, the pointer's value is copied to the stack, and this copy is the value that the add_element() function is referring to. When you alter the pointer's value, you are modifying the copy placed on the stack, not the original pointer.
If you want to alter the original pointer (as if it was passed by reference and not by value) you need to use a double pointer.
Try this variant:
int add_element(struct list **list_, void *v)
{
struct list *node = malloc(sizeof(struct list));
node->value = *((int*)v);
node->next = NULL;
if(*list_ == NULL) // dereferencing the double pointer will access the original pointer
{
*list_ = node; // this will change the original pointer
printf("(*list_)->value = %d\n", (*list_)->value); // correct copy
return 0;
}
//TODO if not first then add at end..
return 0;
}
int main()
{
struct list *l = initialize(); // l = NULL
int i = 10;
add_element(&l,&i); // notice you are now passing the address of l instead of its value
if(l == NULL) printf("l == NULL!\n");
printf("l->value = %d\n", l->value); //should work now
return 0;
}
For starters the function initialize
struct list *initialize(void)
{
struct list * l = NULL;
return l;
}
does not make great sense. You can just write in main
struct list *l = NULL;
Or the function initialize can look like
inline struct list *initialize(void)
{
return NULL;
}
The function add_element deals with a copy of the passed list.
int add_element(struct list *list_, void *v);
So any changes of the copy do not influence on the original list. Also it is unclear why the second parameter has the type void * instead of the type int.
You have to pass the list by reference to the function.
The function can look the following way
int add_element( struct list **head, int value )
{
struct list *node = malloc( sizeof( struct list ) );
int success = node != NULL;
if ( success )
{
node->value = value;
node->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = node;
}
return success;
}
and called for example like
int i = 10;
if ( !add_element( &l, i ) )
{
puts( "Error: not enough memory." );
}
Here is a demonstrative program
#include <stdio.h>
#include <stdlib.h>
struct list
{
int value;
struct list *next;
};
static inline struct list * initialize( void )
{
return NULL;
}
int add_element( struct list **head, int value )
{
struct list *node = malloc( sizeof( struct list ) );
int success = node != NULL;
if ( success )
{
node->value = value;
node->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = node;
}
return success;
}
void output( struct list *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->value );
}
puts( "NULL" );
}
int main(void)
{
struct list *head = initialize();
const int N = 10;
for ( int i = 0; i < N; i++ )
{
add_element( &head, i );
}
output( head );
return 0;
}
Its output is
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> NULL
Pay attention to that if a new node is appended to the tail of the list then it is better to define the list as a two-sided singly-linked list.
I am working on a problem for a class and we're learning linked lists in C. I was given a section of code to complete, specifically the delete a node section and I'm having a problem deleting head. Every time I try to delete head I receive a segmentation fault. Can someone tell me what I'm doing wrong?
EDIT2
My teacher wrote everything but the lookup and delete functions.
I have fixed the glaring errors pointed out by the gentleman from Moscow and Mr. Petriuc, however the code still doesn't run. It does compile, but there is still a problem in head.
Here is the full code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "linkedList.h"
// keep an unsorted array of char *'s, strings.
/*
Create an empty node, return 0 if fail, 1 if succeed
*/
struct node * createNode() {
struct node *p = (struct node *) malloc(sizeof(struct node));
if (p == NULL) return 0;
p->prev = p->next = NULL;
p->data = NULL;
}
/*
Lookup string in the list, return pointer to node of first occurence, NULL if not found.
*/
struct node * lookup(struct node *head, char *s) {
struct node *p;
for(p=head; p!=NULL; p=p->next){
if(strcmp(s,p->data)==0){
return p;
}
// just like print, but check if strcmp(s, p->data) == 0, and if so then return p
}
return NULL;
}
/*
Insert new string into the linked list, return 1 if success, 0 if fail.
*/
int insert(struct node **head, char *newS, int insertDuplicate) {
struct node *p = lookup(*head, newS);
if (p == NULL || insertDuplicate) {
// create a new node, put it at the front.
p = createNode();
if (p == NULL) return 0;
// put the string in the new node
p->data = (char *) malloc(sizeof(char) * (1 + strlen(newS)));
if (p->data == NULL) return 0;
strcpy(p->data, newS);
// note: make changes and use old head before setting the new head...
p->next = *head; // next of new head is previous head
if (*head != NULL)
(*head)->prev = p; // previous of old head is new head
*head = p; // set the new head
}
return 1;
}
/*
Remove string from list if found, return 1 if found and deleted, 0 o/w.
*/
int delete(struct node **head, char *s) {
struct node *p,*pr,*ne;
// first do a lookup for string s, call lookup.
p=lookup(*head, s);
if(p==*head){
*head = p->next;
free(p);
return 1;
}
if(p!=NULL){
printf("%s",p);
pr = p->prev;
ne = p->next;
free(p->data);
free(p);
if(pr==NULL||ne==NULL){
return 0;
}
pr->next=ne;
ne->prev=pr;
// if lookup returns NULL, done, return 0.
// if lookup returns p, not NULL,
// pr = p->prev, ne = p->next
// set pr->next to ne, ne->prev to pr
// but what if pr or ne is NULL
// and note that we need node **head because if delete head,
// need to update head pointer back in calling function, in
// here if you want head probably do *head. like in insert.
// also, before the pointer to the one you're deleting is gone,
// free p->data and p.
return 1;
}
return 0;
}
void print(struct node *head) {
struct node *p;
for(p = head; p != NULL ; p = p->next) {
printf("%s\n", p->data);
}
}
You are doing
p->next = *head;
But p is not assigned anywhere.
Your function does not make sense. You call the function lookup three times.
Moreover you use pointers that were not initialized like for example
p->next = *head;
or
printf("%s",p);
pr = p->prev;
ne = p->next;
The function can be written the following way
int delete( struct node **head, char *s )
{
int success;
struct node *target = lookup( *head, s );
if ( ( success = target != NULL ) )
{
if ( target->prev != NULL )
{
target->prev->next = target->next;
}
else
{
*head = target->next;
}
if ( target->next != NULL )
{
target->next->prev = target->prev );
}
free( target );
}
return success;
}
Take into account that the second parameter of the function and the corresponding parameter of the function lookup should be declared with qualifier const
int delete( struct node **head, const char *s ) ;
^^^^^
struct node * lookup( struct node *head, const char *s );
^^^^^^
Simplified delete() function. I inlined lookup() because the function as it is is worthless (you need a pointer to pointer, not a pointer to act upon)
/*
Remove string from list if found, return 1 if found and deleted, 0 o/w.
*/
int delete(struct node **head, char *s) {
struct node *tmp;
// first do a lookup for string s, no need to call call lookup.
for( ;*head; head = &(*head)->next ){
if (!strcmp( (*head)->data, s)) break;
}
if (!*head) return 0; // not found
tmp = *head
*head = tmp->next
free(tmp);
return 1;
}
Here's my linked list it contains a string version of keys which holds a string representation of contents:
struct node{
char key[10];
char content;
struct node *next;
};
struct node *head=(struct node *) NULL;
struct node *tail=(struct node *) NULL;
struct node * initinode(char *key, char content)
{
struct node *ptr;
ptr = (struct node *) calloc( 1, sizeof(struct node ) );
if( ptr == NULL )
return (struct node *) NULL;
else {
strcpy( ptr->key, key );
ptr->content = content;
return ptr;
}
}
void printnode( struct node *ptr )
{
printf("Key ->%s\n", ptr->key );
printf("Contents ->%d\n", ptr->content );
}
void printlist( struct node *ptr )
{
while( ptr != NULL )
{
printnode( ptr );
ptr = ptr->next;
}
}
void add( struct node *new )
{
if( head == NULL )
head = new;
tail->next = new;
tail->next = NULL;
tail= new;
}
struct node * searchname( struct node *ptr, char *key )
{
while( strcmp( key, ptr->key ) != 0 ) {
ptr = ptr->next;
if( ptr == NULL )
break;
}
return ptr;
}
//-----------------------------add to the list number of files and print list
int file_count = 0;
DIR * dirp;
struct dirent * entry;
dirp = opendir(cwd);
while ((entry = readdir(dirp)) != NULL)
{
if (entry->d_type == DT_REG) { /* If the entry is a regular file */
file_count++;
}
}
printf("%d \n",file_count);
char file=(char)file_count;
closedir(dirp);
ptr=initinode(files, file);
add(ptr);
printlist( head );
//-----------------------------------casting
In addtion to that question I want to add different datatypes to my list in its string represented form. I want to try casting it to a string but it seems the method I used for this would not work on others. And if you suggest diving a void dataype for the list please explain thoroughly.
Thank you
In your code, I have a comment here
void add( struct node *new )
{
if( head == NULL )
head = new;
tail->next = new; // Making tail point to next node
tail->next = NULL; // but, immediately setting tail to NULL --> problem
tail= new; // tail pointing to new but connection to previous node lost
}
I feel that the function could be
void add( struct node *new )
{
if( head == NULL ) {
head = new;
tail = new; // Grow at tail and keep head static
}
else {
tail->next = new; // Connect current node to next
tail= new; // Move tail to new node
tail->next = NULL; // Since this is the last node, set next to NULL
}
}
There is another point to be considered. In this call, printlist( head ); you are passing the head pointer which is getting updated inside the function. I feel it may be a good idea to make a copy of head and pass the same to the function, so that head always points to first element of the list.
P.S: Please avoid naming a variable as new as it is a keyword in C++