incompatible pointer type in c pointers - c

#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node *next;
};
int insert (struct node *head, int data);
int print (struct node *head);
int main()
{
struct node *head;
head = NULL;
// printf("%d\n",head);
insert(&head,5);
insert(&head,4);
insert(&head,6);
print(&head);
print(&head);
print(&head);
}
int insert(struct node *head,int data) {
if(head == NULL) {
head = malloc(sizeof(struct node));
head->next = NULL;
head->data = data;
// printf("%d\n",data);
}
else {
struct node *tmp = head;
if(tmp->next!=NULL) {
tmp = tmp->next;
}
tmp->next = malloc(sizeof(struct node));
tmp->next->next = NULL;
tmp->next->data = data;
// printf("%d\n",data);
}
}
int print (struct node *head) {
printf("hello entered here\n");
struct node *tmp = head;
if (head == NULL) {
printf("entered null\n");
return;
}
while (tmp != NULL) {
if (tmp->next == NULL) {
printf("%0d", tmp->data);
} else {
printf("%0d -> ", tmp->data);
}
tmp = tmp->next;
}
printf("\n");
}
I got the following warning when i compile it
In function main:
insert.c:16: warning: passing argument 1 of insert from incompatible pointer type
insert.c:17: warning: passing argument 1 of insert from incompatible pointer type
insert.c:18: warning: passing argument 1 of insert from incompatible pointer type
insert.c:19: warning: passing argument 1 of print from incompatible pointer type
insert.c:20: warning: passing argument 1 of print from incompatible pointer type
insert.c:21: warning: passing argument 1 of print from incompatible pointer type
When i run it i will get following output
hello entered here
0 -> 5 -> 6
hello entered here
0 -> 5 -> 6
hello entered here
0 -> 5 -> 6
Please help me remove this warnings.
And can u also help me add a function to remove the node in C
What is the mistake I am doing?
Should i pass **head to the function?

Currently the functions print() and insert() expects to struct node* whereas you pass struct node **. If you want to pass a copy then drop the & in your function calls in your code.
If you want to modify the pointer head pass a pointer to pointer and modify the parameters accordingly:
#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node *next;
};
int insert (struct node **head, int data);
int print (struct node **head);
int main()
{
struct node *head;
head = NULL;
// printf("%d\n",head);
insert(&head,5);
insert(&head,4);
insert(&head,6);
print(&head);
print(&head);
print(&head);
}
int insert(struct node **head,int data){
if(*head == NULL){
*head = malloc(sizeof(struct node));
(*head)->next = NULL;
(*head)->data = data;
// printf("%d\n",data);
}
else {
struct node *tmp = *head;
if(tmp->next!=NULL){
tmp = tmp->next;
}
tmp->next = malloc(sizeof(struct node));
tmp->next->next = NULL;
tmp->next->data = data;
// printf("%d\n",data);
}
}
int print (struct node **head) {
printf("hello entered here\n");
struct node *tmp = *head;
if (*head == NULL) {
printf("entered null\n");
return;
}
while (tmp != NULL) {
if (tmp->next == NULL) {
printf("%0d", tmp->data);
} else {
printf("%0d -> ", tmp->data);
}
tmp = tmp->next;
}
printf("\n");
}

Your insert() smells - too complicated. This is some sort of OO actually.
Here is my way, direct typed:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
// class node_t
typedef struct __node_s *node_t; // Mind the pointer here.
struct __node_s {
int data;
node_t next;
};
node_t node_init(void); // Constructor.
void node_append(node_t, int);
void node_drop_last(node_t);
void node_print(node_t);
void node_fini(node_t); // Destructor.
// end class node_t
int main(void)
{
node_t head = node_init();
node_append(head, 5);
node_append(head, 4);
node_append(head, 6);
node_print(head);
node_drop_last(head);
node_print(head);
node_fini(head);
head = NULL;
return 0;
}
node_t node_init(void)
{
node_t node = malloc(sizeof(struct __node_s));
assert(node);
memset(node, 0, sizeof(struct __node_s));
return node;
}
void node_insert(node_t head, int data)
{
node_t last = head, new = node_init();
for (; last->next; last = last->next);
new->data = data;
last->next = new;
}
void node_drop_last(node_t head)
{
node_t last = head;
if (!head->next)
return;
for (; last->next->next; last - last->next);
node_fini(last->next);
last->next = NULL;
}
void node_print(node_t head)
{
for (node_t this = head->next; this; this = this->next)
{
printf("%d", this->data);
if (this->next)
putchar(' '); // A lot faster!
}
putchar('\n');
}
void node_fini(node_t head)
{
if (head->next)
{
node_fini(head->next);
head->next = NULL;
}
free(head);
}

Related

Assigning NULL to the head node in a linked list in C

Please see the full code below.
I have an initial array named arr.
I'm using a linked list to store some indices via the append function. After I got the indices, I store them in linked list and use clearList to change the corresponding values to 0 (In this example arr[2] and arr[4]).
Finally, I free the memory by calling freeList since i'm done with the linked list.
However, to be able to do same thing again and again, I need to set head to NULL whenever I call freeList. But I cannot. Any idea how to solve this?
Thank you.
#include <stdio.h>
#include "gurobi_c.h"
#include <stdlib.h>
//Gurobi variables
GRBenv *env = NULL;
GRBmodel *model = NULL;
//Gurobi variables
struct Node
{
int data;
struct Node *next;
struct Node *end;
};
void append(struct Node** head_ref, int new_data)
{
struct Node *last = *head_ref;
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = NULL;
new_node->end = new_node;
if (*head_ref == NULL)
{
*head_ref = new_node;
//printf(" ..Init Append %d\n",new_data);
return;
}
last = (*head_ref)->end;
last->next = new_node;
(*head_ref)->end=new_node;
//printf(" ..Append %d\n",new_data);
return;
}
void clearList(struct Node *node, double *arr)
{
int i;
if(node!=NULL)
{
struct Node tmp;
tmp=*(node->end);
while (node != NULL)
{
i=node->data;
arr[i]=0;
//printf(" ..clear %d \n", node->data,(node->end)->data);
node = node->next;
}
}
}
void freeList(struct Node *node)
{
struct Node *tmp,*hd;
hd=node;
while (node != NULL)
{
tmp=node;
node = node->next;
//printf(" ..Free %d \n", tmp->data);
free(tmp);
}
hd=NULL;
}
int main (){
Node *head;
double *arr = (double *) malloc(sizeof(double) * 10);
for(int i=0;i<10;i++)
arr[i]=i;
head=NULL;
printf("Head: %s\n", head);
append(&head,2);
append(&head,4);
clearList(head,arr);
for(int i=0;i<10;i++)
printf("No %d : %.2f\n",i,arr[i]);
freeList(head);
free(arr);
printf("%s", head);
getchar();
return 0;
}
You're already changing the value of head in your append function so you basically need to do the same thing in freeList:
void freeList(struct Node **head_ref)
{
struct Node *tmp,*node;
node=*head_ref;
while (node != NULL)
{
tmp=node;
node = node->next;
//printf(" ..Free %d \n", tmp->data);
free(tmp);
}
*head_ref=NULL;
}
int main (){
/* do stuff */
freeList(&head);
/* do stuff */
}
Just for completeness: Another possible option would be to use a wrapper macro for freeList().
void freeList(struct Node *node)
{
/* ... */
}
#define freeListNull(node) do { \
freeList(node); \
node = NULL; \
} while(0)
int main () {
/* ... */
freeListNull(head);
/* ... */
}
This solution has a similar disadvantage as the version that returns the modified pointer. You can simply forget to use the right call freeListNull(head); and call freeList(head); instead. The best solution is a function freeList() that takes the address of the head pointer as in idk's answer.
I realized it is possible to change the freeList function so that it will return a NULL value. See the updated code below:
#include <stdio.h>
#include "gurobi_c.h"
#include <stdlib.h>
//Gurobi variables
GRBenv *env = NULL;
GRBmodel *model = NULL;
//Gurobi variables
struct Node
{
int data;
struct Node *next;
struct Node *end;
};
void append(struct Node** head_ref, int new_data)
{
struct Node *last = *head_ref;
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = NULL;
new_node->end = new_node;
if (*head_ref == NULL)
{
*head_ref = new_node;
//printf(" ..Init Append %d\n",new_data);
return;
}
last = (*head_ref)->end;
last->next = new_node;
(*head_ref)->end=new_node;
//printf(" ..Append %d\n",new_data);
return;
}
void clearList(struct Node *node, double *arr)
{
int i;
if(node!=NULL)
{
struct Node tmp;
tmp=*(node->end);
while (node != NULL)
{
i=node->data;
arr[i]=0;
//printf(" ..clear %d \n", node->data,(node->end)->data);
node = node->next;
}
}
}
Node* freeList(struct Node *node)
{
struct Node *tmp;
while (node != NULL)
{
tmp=node;
node = node->next;
printf(" ..Free %d \n", tmp->data);
free(tmp);
}
return NULL;
}
int main (){
Node *head;
double *arr = (double *) malloc(sizeof(double) * 10);
for(int i=0;i<10;i++)
arr[i]=i;
head=NULL;
printf("Head: %s -> null as expected\n", head);
append(&head,2);
append(&head,4);
clearList(head,arr);
for(int i=0;i<10;i++)
printf("No %d : %.2f\n",i,arr[i]);
printf("Head: %s -> Not null as linkedlist is not freed\n", head);
head=freeList(head);
printf("Head: %s -> Again null as expected\n", head);
free(arr);
printf("%s", head);
getchar();
return 0;
}

I feel confusion in linked list.what is the solution?

Specially i feel confusion about passing the head in function.Would any one kindly explain?
#include<stdio.h>
struct node
{
int data;
struct node *next;
};
struct node *makeNode(int item)
{
struct node *newNode = (struct node *)malloc(sizeof(struct node));
newNode->data = item;
newNode->next = NULL;
return newNode;
}
void traverse(struct node *head)
{
struct node *ptr = head;
while(ptr != NULL)
{
printf("%d ",ptr->data);
ptr = ptr->next;
}
printf("\n");
}
void push(struct node **headRef, int data)
{
struct node *newNode = makeNode(data);
newNode->next = *headRef;
*headRef = newNode;
}
void append(struct node **headRef, int data)
{
struct node *newNode = makeNode(data);
struct node *ptr = *headRef, *temp;
if( ptr == NULL )
{
*headRef = newNode;
return;
}
while(ptr != NULL)
{
temp = ptr;
ptr = ptr->next;
}
temp->next = newNode;
}
void deleteData(struct node **headRef, int key)
{
struct node *ptr = *headRef, *prevNode;
//If key is in head node
if( (ptr->data == key) && (ptr != NULL) )
{
*headRef = ptr->next;
free(ptr);
return;
}
while( (ptr != NULL) && (ptr->data!=key) )
{
prevNode = ptr;
ptr = ptr->next;
}
if(ptr == NULL)
printf("Underflow or Key not found.\n");
else
{
prevNode->next = ptr->next;
free(ptr);
}
}
int main()
{
struct node *head = NULL;
int data;
printf("Enter Positive Data:\n");
scanf("%d",&data);
while( data>=0 )
{
append(&head,data);
in this function , pass the address of head.
scanf("%d",&data);
}
printf("\nTraversing...\n");
traverse(head);
but in this function why i only pass the head?
printf("\n\nEnter a data to delete:\n");
scanf("%d",&data);
deleteData(&head,data);
printf("\nTraversing...\n");
traverse(head);
}
In Function traverse
void traverse(struct node *head) {
......
......
}
Traverse function has a parameter head which is of type struct node pointer.
Hence to call traverse function you must pass an argument of type struct node pointer.
In main function you defined head as struct node *head = NULL;
that's why you are making call to the function like traverse(head).
In Function append
void append(struct node **headRef, int data)
{
....
....
}
The argument headref is of type 'pointer to pointer'.
Pointer to Pointer variable stores the address of pointer
Hence, you must pass address of pointer as argument and you make call to append function as append(&head,data)
To use pointer as a parameter in append function
Change the return type of you function from void to struct node* and return the headRef pointer.
struct node* append(struct node *headRef, int data)
{
struct node *newNode = makeNode(data);
struct node *ptr = headRef, *temp;
if( ptr == NULL )
{
headRef = newNode;
return headRef;
}
while(ptr != NULL)
{
temp = ptr;
ptr = ptr->next;
}
temp->next = newNode;
return headref;
}
Inside the main function, you should call append function like this.
head = append(head,data); //since append function is now returning a pointer
Complete code to append nodes using single pointer
#include<stdio.h>
struct node
{
int data;
struct node * next;
};
struct node * makeNode(int item)
{
struct node * newNode = (struct node * ) malloc(sizeof(struct node));
newNode -> data = item;
newNode -> next = NULL;
return newNode;
}
void traverse(struct node * head)
{
struct node * ptr = head;
while (ptr != NULL)
{
printf("%d ", ptr -> data);
ptr = ptr -> next;
}
printf("\n");
}
struct node * append(struct node * headRef, int data)
{
struct node * newNode = makeNode(data);
struct node * ptr = headRef, * temp;
if (ptr == NULL)
{
headRef = newNode;
return headRef;
}
while (ptr != NULL)
{
temp = ptr;
ptr = ptr -> next;
}
temp -> next = newNode;
return headRef;
}
int main()
{
struct node * head = NULL;
int data;
printf("Enter Positive Data:\n");
scanf("%d", & data);
while (data >= 0)
{
head = append(head, data);
scanf("%d", & data);
}
printf("\nTraversing...\n");
traverse(head);
return 0;
}
Function append may alter the value of head (which is a pointer). The signature is therefore void append(struct node **headRef, int data); note the **, which denotes a pointer to a pointer. So you have to pass the address of the pointer in order to allow append to change the pointer, i.e. call append(&head,data).
Function traverse, in contrast, needs not to alter the value of head, so it consumes the pointer directly (and not a pointer to that pointer). The signature is therefore void traverse(struct node *head); note the single *. Hence, call it like traverse(head).
include
struct node
{
int data;
struct node *next;
};
struct node *makeNode(int item)
{
struct node *newNode = (struct node *)malloc(sizeof(struct node));
newNode->data = item;
newNode->next = NULL;
return newNode;
}
i got bug in the above line
void traverse(struct node *head)
{
struct node *ptr = head;
while(ptr != NULL)
{
printf("%d ",ptr->data);
ptr = ptr->next;
}
printf("\n");
}
i know that there is no need to return the pointer .is it true? if it is true why need to give a return type in the following function?
struct node* append(struct node *headRef, int data)
{
struct node *newNode = makeNode(data);
struct node *ptr = headRef, *temp;
if( ptr == NULL )
{
headRef = newNode;
return headRef;
}
while(ptr != NULL)
{
temp = ptr;
ptr = ptr->next;
}
temp->next = newNode;
return headref;
}
int main()
{
struct node *head = NULL;
int data;
printf("Enter Positive Data:\n");
scanf("%d",&data);
while( data>=0 )
{
head=append(head,data);
scanf("%d",&data);
}
printf("\nTraversing...\n");
traverse(head);
}

Linked List using recursion - Unexpected Output

I found this on Internet to reverse a list using recursion and applied it in codeblocks but the output only reverse prints last two Insert call from main function. It skips the first three Insert calls. Why? I did search for this problem here but I failed to understand them as I'm a beginner. Kindly help
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node * head;
struct Node* Insert (struct Node* head, int data)
{
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
if(head == NULL)
{
head = temp;
return;
}
struct Node* temp2 = head;
while(temp2->next != NULL)
{
temp2 = temp2->next;
}
temp2->next = temp;
}
void reversePrint(struct Node* head)
{
if(head == NULL)
{
printf("\n");
return;
}
reversePrint(head->next);
printf(" %d ", head->data);
return;
}
int main()
{
struct Node* head = NULL;
head = Insert(head,2);
head = Insert(head,7);
head = Insert(head,3);
head = Insert(head,1);
head = Insert(head,4);
reversePrint(head);
return 0;
}
O/P : 4 1
NOTES:
Don't cast the return of value of malloc
You declared two *head and confused yourself
No need to pass pointer to function and return pointer when you have head declared as global. Which is not a good idea but I followed your code.
Code:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node * head;
void Insert (int data)
{
struct Node* temp = malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
if(head == NULL)
{
head = temp;
return;
}
struct Node* temp2 = head;
while(temp2->next != NULL)
{
temp2 = temp2->next;
}
temp2->next = temp;
}
void reversePrint(struct Node* head)
{
if(head == NULL)
{
printf("\n");
return;
}
reversePrint(head->next);
printf(" %d ", head->data);
return;
}
int main()
{
Insert(2);
Insert(7);
Insert(3);
Insert(1);
Insert(4);
reversePrint(head);
return 0;
}
OUTPUT:
4 1 3 7 2

unable to create new node where head pointer points to in c?

say I have the following code for inserting a node at the end to a linkedlist:
int main() {
struct Node* head = NULL;
newNode(head, 1);
newNode(head, 2);
newNode(head, 3);
print(head);
return 0;
}
void newNode(struct Node* head, int val) {
struct Node* curr_p = head;
struct Node* new_p = malloc(sizeof(struct Node));
new_p->data = val;
new_p->next = NULL;
if (head == NULL) {
curr_p = new_p;
// printf("head %d \n", head->data);
}
else{
while (curr_p->next != NULL) {
curr_p = curr_p->next;
}
curr_p->next = new_p;
}
}
void print(struct Node* head) {
struct Node* curr_p = head;
while (curr_p != NULL) {
printf("%d\n", curr_p->data);
curr_p = curr_p->next;
}
}
It appears what causes the error is in the if statement block where head == NULL, the head node pointer seems to unable to point to new node. I always ended up with a segmentation fault. any reason for this?
I guess that your fault is that you are passing the head pointer in value not in reference so the code doesn't change it's value because it just copies the pointer
so your code should look like this
newNode(struct Node** head , int val ) {
struct Node* curr_p = *head;
/*
*/
if(curr_p == NULL ) {
*head = new_p;
}/*....*/
}
and in the main
newNode(&head,1)
and the finale code would be
#include <stdio.h>
#include <stdlib.h>
struct Node{
int data;
struct Node * next;
};
void newNode(struct Node** head, int val) {
struct Node* curr_p = *head;
struct Node* new_p =malloc(sizeof(struct Node));
new_p->data = val;
new_p->next = NULL;
if ( curr_p == NULL) {
*head = new_p;
// printf("head %d \n", head->data);
}
else{
while (curr_p->next != NULL) {
curr_p = curr_p->next;
}
curr_p->next = new_p;
}
}
void print(struct Node* head) {
struct Node* curr_p = head;
while (curr_p != NULL) {
printf("%d\n", curr_p->data);
curr_p = curr_p->next;
}
}
int main() {
struct Node* head = NULL;
newNode(&head, 1);
newNode(&head, 2);
newNode(&head, 3);
print(head);
return 0;
}
and actually you don't have to use curr_p in the print function because the head pointer in the print function it's just a copy of the head pointer of the main function so it wouldn't change it's value if you do something like head = head->next ; in the print function .
You have not specified that where you are getting segmentation fault but my strong guess is that you would be getting at - printf("head %d \n", head->data);. Why? Because with your present code head is NULL (that's what you are passing from your main method) and then you try to de-reference a NULL then you WILL segmentation fault.
You must only de-reference a valid pointer. If the pointer variable is holding NULL or some uninitialized/default value then de-referencing it will result in segmentation fault.
Below is the fixed IF block.
if (head == NULL) {
head = new_p;
printf("head %d \n", head->data);
}

Pointers Linked Lists C

Did I do this right? I'm getting a strange error here...
linked.c: In function ‘push’:
linked.c:50:19: warning: assignment from incompatible pointer type [enabled by default]
linked.c: In function ‘main’:
linked.c:146:9: error: incompatible type for argument 1 of ‘push’
linked.c:45:6: note: expected ‘struct node **’ but argument is of type ‘struct node’
~/swen250/CLinkedList$ gcc -o linked linked.c
linked.c: In function ‘push’:
linked.c:50:19: warning: assignment from incompatible pointer type [enabled by default]
~/swen250/CLinkedList$ gcc -o linked linked.c
linked.c: In function ‘pop’:
linked.c:63:19: error: request for member ‘data’ in something not a structure or union
linked.c:64:20: error: request for member ‘next’ in something not a structure or union
linked.c: In function ‘copyList’:
linked.c:106:9: warning: passing argument 1 of ‘appendNode’ from incompatible pointer type [enabled by default]
linked.c:75:6: note: expected ‘struct node **’ but argument is of type ‘struct node *’
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
static int length(struct node** head);
static void push(struct node** head, int data);
static int pop(struct node** head);
static void appendNode(struct node** head, int data);
static struct node *copyList(struct node** head);
static void printList(struct node** head);
/************************************************************
length - return length of a list
************************************************************/
int length(struct node** head) {
int count = 0;
struct node* current = NULL;
current = *head;
while (current != NULL) {
current = current->next;
++count;
}
return count;
}
/************************************************************
push - add new node at beginning of list
************************************************************/
void push(struct node** head, int data) {
struct node* new_ptr = NULL;
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = *head;
*head = new_ptr;
}
/************************************************************
pop - delete node at beginning of non-empty list and return its data
************************************************************/
int pop(struct node** head) {
int val = 0;
struct node* temp = NULL;
if (*head != NULL) {
val = head->data;
temp = head->next;
free(head);
*head = temp;
}
return(val);
}
/************************************************************
appendNode - add new node at end of list
************************************************************/
void appendNode(struct node** head, int data) {
struct node* current = NULL;
struct node* previous = NULL;
struct node* new_ptr = NULL;
current = *head;
previous = current;
while (current != NULL) {
previous = current;
current = current->next;
}
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = NULL;
previous = new_ptr;
}
/************************************************************
copyList - return new copy of list
************************************************************/
struct node* copyList(struct node** head) {
struct node* copy = NULL;
struct node* current = NULL;
struct node* new_ptr = NULL;
/* Copy current head to copy */
current = *head;
while (current != NULL) {
appendNode(copy, current->data);
current = current->next;
}
return copy;
}
/************************************************************
printList - print linked list as "List: < 2, 5, 6 >" (example)
************************************************************/
void printList(struct node** head) {
struct node* current = NULL;
printf("List: < ");
current = *head;
if (current == NULL)
printf("none ");
while (current != NULL) {
printf("%d", current->data);
current = current->next;
if (current != NULL)
printf(", ");
}
printf(" >\n");
}
void main() {
int i; // index used for loops
struct node *list_a; // a new list
struct node *list_a_copy; // copy of list
list_a = NULL; // initialize empty list
list_a_copy = NULL; // initialize empy list
// test push
for (i = 0; i < 4; ++i)
push(&list_a, i);
// test length
printf("Length of list = %d\n", length(&list_a));
// test print head list
printf("head:\n");
printList(&list_a);
// test append node
for (i = 4; i < 8; ++i)
appendNode(&list_a, i);
// test print head list
printf("head(append):\n");
printList(&list_a);
// make a copy of list
list_a_copy = copyList(&list_a);
// test pop head list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(&list_a));
// test print copy list
printf("head copy:\n");
printList(&list_a_copy);
// test pop copy list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(&list_a_copy));
}
The issue is with the way how double pointers are used.
Here is the full working code:
I have made some changes on the way how double pointers were used.
You can see the changes in pop function and copyList function.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
static int length(struct node** head);
static void push(struct node** head, int data);
static int pop(struct node** head);
static void appendNode(struct node** head, int data);
static struct node *copyList(struct node** head);
static void printList(struct node** head);
/************************************************************
length - return length of a list
************************************************************/
int length(struct node** head) {
int count = 0;
struct node* current = NULL;
current = *head;
while (current != NULL) {
current = current->next;
++count;
}
return count;
}
/************************************************************
push - add new node at beginning of list
************************************************************/
void push(struct node** head, int data) {
struct node* new_ptr = NULL;
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = *head;
*head = new_ptr;
}
/************************************************************
pop - delete node at beginning of non-empty list and return its data
************************************************************/
int pop(struct node** head) {
int val = 0;
struct node* temp = NULL;
if (*head != NULL) {
val = (*head)->data;
temp = (*head)->next;
free(*head);
*head = temp;
}
return(val);
}
/************************************************************
appendNode - add new node at end of list
************************************************************/
void appendNode(struct node** head, int data) {
struct node* current = NULL;
struct node* previous = NULL;
struct node* new_ptr = NULL;
current = *head;
previous = current;
while (current != NULL) {
previous = current;
current = current->next;
}
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = NULL;
previous = new_ptr;
}
/************************************************************
copyList - return new copy of list
************************************************************/
struct node* copyList(struct node** head) {
struct node* copy = NULL;
struct node* current = NULL;
struct node* new_ptr = NULL;
/* Copy current head to copy */
current = *head;
while (current != NULL) {
appendNode(&copy, current->data);
current = current->next;
}
return copy;
}
/************************************************************
printList - print linked list as "List: < 2, 5, 6 >" (example)
************************************************************/
void printList(struct node** head) {
struct node* current = NULL;
printf("List: < ");
current = *head;
if (current == NULL)
printf("none ");
while (current != NULL) {
printf("%d", current->data);
current = current->next;
if (current != NULL)
printf(", ");
}
printf(" >\n");
}
void main() {
int i; // index used for loops
struct node *list_a; // a new list
struct node *list_a_copy; // copy of list
list_a = NULL; // initialize empty list
list_a_copy = NULL; // initialize empy list
// test push
for (i = 0; i < 4; ++i)
push(&list_a, i);
// test length
printf("Length of list = %d\n", length(&list_a));
// test print head list
printf("head:\n");
printList(&list_a);
// test append node
for (i = 4; i < 8; ++i)
appendNode(&list_a, i);
// test print head list
printf("head(append):\n");
printList(&list_a);
// make a copy of list
list_a_copy = copyList(&list_a);
// test pop head list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(&list_a));
// test print copy list
printf("head copy:\n");
printList(&list_a_copy);
// test pop copy list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(&list_a_copy));
}
From the error log, I notice that you have incompatible types multiples time. It would help if you post your main.cpp as well.
p.s Like Mike G said, double pointer is really excessive. You can implement a linked list using a single pointer.
Problem is in your pop() function...take a look.
you are assigning
val=head->data;
temp = head->next;
also you are freeing the head and then reassigning.
you should do like this
val=(*head)->data;
temp=(*head)->next;
and while freeing memory...free the temp and reassign head to its next.

Resources