Search code examples
cpointerslinked-listside-effects

Weird side effect using operator '->' in c


I get this weird side effect while using operator '->' in code I wrote in C. The pointer which I used -> on , is changed to have some garbage.

More specifically:

I have the following structs:

typedef void* ListElement ;

typedef  struct List_t* List ;

typedef struct Node_t* Node;

Struct Node_t {
  ListElement data ;
  Node next;
}

Struct List_t {
  Node* head;
  Node* current
}

when I use the following ListGetFirst(), I get wired behavior :

ListElement ListGetFirst(List list)
{
  if( list == NULL || list->head==NULL)
  {
    return NULL;
  }
  list->current=list->head;
  Node* head =list->head; // here is the problem
  ListElement data = (*head)->data;
  return data;
}

when I used debugger I figured out that the pointer list->head is changed on the marked aformentioned line .

I realy have no idea why, and I didn't knew that '->' can have side effect

thanks in advance


Solution

  • Gah, pointers hidden behind typedefs; unless the type's meant to be totally opaque, that's almost always bad juju. For my benefit, I'm going to take out the typedefs so I have an easier time seeing what you're really playing with.

    struct Node_t {   
      void *data ;   
      struct Node_t *next; 
    };
    
    struct List_t {   
      struct Node_t **head;   
      struct Node_t **current; 
    };
    
    void *ListGetFirst(struct List_t *list)
    {
      if( list == NULL || list->head==NULL
      {        
         return NULL;
      }
      list->current=list->head;             
      struct Node_t **head =list->head; // here is the problem
      void *data = (*head)->data;
      return data;           
    }           
    

    I got nuthin'. Types all appear to match up. The -> operator most emphatically does not have any side effects; all it does is dereference a pointer. The extra level of indirection for head and current in struct List_t is a head-scratcher, and it makes me wonder if they're being allocated or assigned correctly. All I can figure is that list->head isn't pointing to memory that you actually own, and is getting overwritten somehow when you reach that point (IOW, you've invoked undefined behavior somewhere else in your code).

    In short, the problem isn't in the code that you've posted. It's probably where you allocate and assign list elements.