Reputation: 303
I'm attempting to create a knapsack program out of the use of linked list but ive run into an issue that i can quite figure out. In nearly all of my functions im getting this error on the same line of an incompatible pointer type and i'm confused on how to fix it. The other issue im running into is a return makes integer from pointer without a cast
errors. Full code and errors below. The error lies in the knapsack.c
file, test_knapsack.c
is just given for a main function example for testing purposes.
ERRORS
knapsack.c: In function ‘KnapsackRemove’:
knapsack.c:37:16: warning: return makes integer from pointer without a cast [-Wint-conversion]
return NULL;
^
knapsack.c:47:29: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
knapsack=(*present)->next;
knapsack.c:59:12: warning: return makes integer from pointer without a cast [-Wint-conversion]
return *knapsack;
^
knapsack.c: In function ‘KnapsackPrint’:
knapsack.c:69:17: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
temp=(*temp)->next;
^
knapsack.c: In function ‘KnapsackItemCount’:
knapsack.c:82:13: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
temp=(*temp)-> next;
^
knapsack.c: In function ‘KnapsackSize’:
knapsack.c:94:13: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
temp=(*temp)-> next;
knapsack.c
#include <stdio.h>
#include "knapsack.h"
#include <stdlib.h>
listitemptr KnapsackAdd(listitemptr *knapsack, int item){
if(knapsack == NULL){
listitemptr newer = (listitemptr)malloc(sizeof(listitemptr));
newer-> item = item;
newer-> count = 1;
newer-> next = NULL;
return newer;
}else{
listitemptr *temp = knapsack;
listitemptr previous = NULL;
while(temp!= NULL){
if((*temp)->item == item){
(*temp)->count=(*temp)->count+1;
break;
}
previous = *temp;
*temp = (*temp)->next;
}
if(temp == NULL){
listitemptr newer = (listitemptr)malloc(sizeof(listitemptr));
newer->item = item;
newer->count =1;
newer->next = NULL;
previous->next = newer;
return newer;
}
return *temp;
}
}
int KnapsackRemove(listitemptr *knapsack, int item){
if(knapsack==NULL)
return NULL;
listitemptr *present = knapsack;
listitemptr previous = NULL;
while(present != NULL){
if((*present)->item == item){
if((*present)-> count > 1){
(*present)->count=(*present)->count-1;
}else{
if(previous==NULL){
knapsack=(*present)->next;
}else{
previous->next=(*present)->next;
free(present);
}
}
break;
}
previous=*present;
*present=(*present)->next;
}
return *knapsack;
}
void KnapsackPrint(const listitemptr *knapsack){
if(knapsack == NULL)
printf("(nothing)\n");
else{
const listitemptr *temp = knapsack;
while(temp!= NULL){
printf("%d (%d), ",(*temp)->item, (*temp)->count);
temp=(*temp)->next;
}
printf("\n");
}
}
unsigned int KnapsackItemCount(const listitemptr *knapsack, int item){
if(knapsack== NULL)
return 0;
const listitemptr *temp = knapsack;
while(temp != NULL){
if((*temp)-> item== item)
return (*temp)-> count;
temp=(*temp)-> next;
}
return 0;
}
unsigned int KnapsackSize(const listitemptr *knapsack){
if(knapsack == NULL)
return 0;
const listitemptr *temp = knapsack;
unsigned int sum = 0;
while(temp!= NULL){
sum+= (*temp)-> count;
temp=(*temp)-> next;
}
return sum;
}
knapsack.h
/* knapsack.h
* implements simple knapsack data structure as a linked list
* NOTE: a function may update the value of input argument *knapsack if it changes the first node of the knapsack to another node. Such a change include the case when an item is added to an empty knapsack
*/
typedef struct listitem* listitemptr;
struct listitem {
int item; // actual int item
unsigned int count; // number of the same item in the knapsack; should be >= 1
listitemptr next; // pointer to next item
};
listitemptr KnapsackAdd(listitemptr *knapsack, int item);
int KnapsackRemove(listitemptr *knapsack, int item);
void KnapsackPrint(const listitemptr *knapsack);
unsigned int KnapsackItemCount(const listitemptr *knapsack, int item);
unsigned int KnapsackSize(const listitemptr *knapsack);
test_knapsack.c
#include "knapsack.h"
#include <stdio.h>
#include <assert.h>
int main(){
//knapsack k1
listitemptr head=KnapsackAdd(NULL,10);
KnapsackAdd(&head,-20);
KnapsackAdd(&head,10);
KnapsackAdd(&head,15);
KnapsackAdd(&head,-20);
KnapsackAdd(&head,10);
KnapsackPrint(&head);
int count=KnapsackItemCount(&head,10);
assert(count==3);
count=KnapsackItemCount(&head,8);
assert(count==0);
count=KnapsackSize(&head);
assert(count==6);
//knapsack2
listitemptr head2=KnapsackAdd(NULL,5);
KnapsackAdd(&head2,10);
KnapsackAdd(&head2,15);
KnapsackAdd(&head2,20);
KnapsackAdd(&head2,-5);
KnapsackPrint(&head2);
KnapsackRemove(&head2,15);
count=KnapsackSize(&head2);
assert(count==4);
count=KnapsackItemCount(&head2,15);
assert(count==0);
KnapsackRemove(&head2,10);
count=KnapsackSize(&head2);
assert(count==3);
KnapsackAdd(&head,10);
count=KnapsackSize(&head2);
assert(count==3);
count=KnapsackSize(&head);
assert(count==7);
return 0;
}
Upvotes: 2
Views: 188
Reputation: 359
Regarding the warning -
knapsack.c:37:16: warning: return makes integer from pointer without a cast [-Wint-conversion]
return NULL;
The definition of NULL is compiler dependent, probably in your compiler NULL
is defined as (void*)0
, therefore you are trying to return a pointer but your function is defined as int KnapsackRemove(...)
so it expects an int value to be returned.
Regarding -
knapsack.c:59:12: warning: return makes integer from pointer without a cast [-Wint-conversion]
return *knapsack;
You are trying to return a listitemptr
type from a function returning an int.
regarding the other warnings, you are trying to assign listitemptr
to a listitemptr*
type. (*present)->next
is of type listitemptr
and knapsack
is of type listitemptr*
.
Upvotes: 2
Reputation:
Looking at the line
temp=(*temp)->next;
temp
is defined as const listitemptr *temp
, meaning its type is const listitemptr *
.
To find the type of (*temp)->next
, we can look at its pieces. We already know temp
is a const listitemptr *
, so de-referencing it results in a listitemptr
.
Looking at your source, we can then find the type of next
,
struct listitem {
listitemptr next; // pointer to next item
};
now we can see that next
, and therefore (*temp)->next
, has the type listitemptr
.
So you are assigning a listitemptr
to a const listitemptr *
.
It looks like most of these errors are caused by confusing listitemptr
for a pointer to listitemptr*
.
Upvotes: 1