Struct and Pointer Segmentation Error in C

2020-05-01 17:55发布

问题:

can anyone help with this segmentation error i keep getting. this code is simple but the error is so hard to figure out.

struct Link {
  int key;
  unsigned data: 2;
  struct Link *next;
  struct Link *previous;
};

struct Link* addInOrder(struct Link *, struct Link);

int main() {
  struct Link *head;
  struct Link data1;
  struct Link data2;
  struct Link data3;
  data1.key = 25;
  data1.data = 1;
  data1.next = NULL;
  data2.key = 50;
  data2.data = 0;
  data2.next = NULL;
  data3.key = 100;  
  data3.data = 2; 
  data3.next = NULL;
  head = NULL;
  head = addInOrder(head, data2);
}

struct Link* addInOrder(struct Link *srt, struct Link l) {
  if(!srt) {
    return &l;
  }

  struct Link *temp = srt;
  while(temp->next && l.key > temp->key)
    temp = temp->next;

  printf("here\n");

  if(l.key > temp->key) {
    printf(" 1\n");
    temp->next = &l;
    l.previous = temp;
  }
  else {
    printf(" 2\n");
    l.previous = temp->previous;
    l.next = temp;
    printf( "2.2\n");
    if(temp->previous) {
      //printf("%i\n",temp->previous->key);
      temp->previous->next = &l;
    }
    printf(" 2.3\n");
    temp->previous = &l;
  }
  return srt;
}

i keep getting an error at the first line in addInOrder(). all the compiler says is Segmentation Error.

Edit: also, if i add printf("..."); right after the if statement and run it ... does not print

回答1:

You're passing the second argument of addInOrder() by value (struct Link l). This creates a copy of the argument when you call the function, and in addInOrder(), l exists on the stack. You're then returning the address of the local variable and assigning it to head, but when the function exits, that variable is out of scope and is deallocated. So you're assigning an invalid address to head, and that results in a segfault.



回答2:

The part (and everywhere &l is used)

if (!srt)
    return &l;

is returning the address of a stack variable. Your addInOrder function should probably have the signature

struct Link* addInOrder(struct Link* srt, struct Link* l);