user4846740
user4846740

Reputation:

Incompatible types error from pointer to pointer

void remove_element(struct Node *list)
{   
    struct Node *temp = list;
    printf("Enter the element value you want to remove");
    int value;
    scanf("%d",&value);
    if(temp->data == value){ //first node is to be deleted
        *list = temp->next; // error here
        free(temp);
    }
}

Error :incompatible types when assigning to type 'struct Node' from type 'struct Node *'| Though this has been successfully compiled

 struct Node *temp = list; 

This line is similar but shows no error.

Upvotes: 1

Views: 143

Answers (3)

Dhruv Roy Talukdar
Dhruv Roy Talukdar

Reputation: 84

First of all the reason why you are getting error is...

*list = temp->next; //not *list it should be list

By doing so your code will compile but you will get unexpected results i think. Because:

list=temp->next // This will make the pointer to constantly point to the head

But i think you are trying to do a linear search. Thus you also need to change the above line to

temp = temp->next;

For your code to work as you expected.

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

As the parameter list is declared like

struct Node *list

then the expression *list used in this statement

*list = temp->next;

has the type struct Node while the right side hand operand has the type struct Node *.

You have to write

list = temp->next;

But in any case pay attention to that the function can invoke undefined behavior when the passed list is empty. And it should search a node for the target value instead of checking only the head node whether it contains the target value.

And the worst is the function even does not change the pointer to the head node because the pointer is passed to the function by value. So this statement

    list = temp->next; // error here

changes a copy of the original pointer to the head node not the original pointer itself declared in main.

The function should be defined at least like

int remove_element( struct Node **list )
{   
    printf( "Enter the element value you want to remove: " );
    int value;
    
    int success = scanf( "%d", &value ) == 1;

    if ( success )
    {
        while ( *list != NULL && ( *list )->data != value )
        {
            list = &( *list )->next;
        }

        success = *list != NULL;

        if ( success )
        {
            struct Node *tmp = *list;
            *list = ( *list )->next;
            free( tmp );
        }
    }

    return success;
}

If in main you have a declaration

struct Node *list = NULL;
//...

then the function must be called like

remove_element( &list );

or something like

if ( remove_element( &list ) )
{
    puts( "A node was removed." );
}

Also it would be better if the function would do only one thing: deleting a node. The prompt for a value that must be deleted should be placed outside the function. In this case the function can be defined the following way

int remove_element( struct Node **list, int value )
{   
    while ( *list != NULL && ( *list )->data != value )
    {
        list = &( *list )->next;
    }

    int success = *list != NULL;

    if ( success )
    {
        struct Node *tmp = *list;
        *list = ( *list )->next;
        free( tmp );
    }

    return success;
}

Here is a demonstrative program.

#include <stdio.h>
#include <stdlib.h>

struct Node
{
    int data;
    struct Node *next;
};
    
    
int push_front( struct Node **list, int data )
{
    struct Node *temp = malloc( sizeof( struct Node ) );
    int success = temp != NULL;

    if ( success )
    {       
        temp->data = data;
        temp->next  = *list;
        *list = temp;
        
    }

    return success;
}

void clear( struct Node **list )
{
    while ( *list != NULL )
    {
        struct Node *temp = *list;
        *list = ( *list )->next;
        free( temp );
    }
}

void display( const struct Node *list )
{
    for ( const struct Node *current = list; current != NULL; current = current->next ) 
    {
        printf( "%d -> ", current->data );
    }
    
    puts( "null" );
}

int remove_element( struct Node **list, int value )
{   
    while ( *list != NULL && ( *list )->data != value )
    {
        list = &( *list )->next;
    }

    int success = *list != NULL;

    if ( success )
    {
        struct Node *tmp = *list;
        *list = ( *list )->next;
        free( tmp );
    }

    return success;
}

int main(void) 
{
    struct Node *list = NULL;
    
    const int N = 10;
    
    for ( int i = N; i != 0; i-- )
    {
        push_front( &list, i );
    }
    
    display( list );
    
    int value = 1;
    
    if ( remove_element( &list, value ) )
    {
        printf( "The element with the value %d was removed.\n", value );
        
    }

    display( list );

    value = 10;
    
    if ( remove_element( &list, value ) )
    {
        printf( "The element with the value %d was removed.\n", value );
        
    }

    display( list );

    value = 5;
    
    if ( remove_element( &list, value ) )
    {
        printf( "The element with the value %d was removed.\n", value );
        
    }

    display( list );

    clear( &list );
    
    display( list );

    return 0;
}

Its output is

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
The element with the value 1 was removed.
2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
The element with the value 10 was removed.
2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
The element with the value 5 was removed.
2 -> 3 -> 4 -> 6 -> 7 -> 8 -> 9 -> null
null

Upvotes: 0

klutt
klutt

Reputation: 31296

struct Node *temp = list;

is the same as

struct Node *temp;
temp = list;

So change the erroneous line to

list = temp->next;

Note that * means slightly different things depending on context. In declarations, it indicates that you want to declare a pointer instead of a regular variable. When used in an expression, it instead means that you want to dereference the pointer. There is no way to dereference it during declaration, which does not cause any problems since that would be undefined behavior anyway.

Upvotes: 5

Related Questions