Segmentation fault while using structs and pointers in C

时间:2017-04-10 02:05:15

标签: c pointers struct stack

I want to implement some basic data structures in C in order to learn how to use pointers, but I got stuck in the first one; I have these two structs:

typedef struct node{
  int value;
  struct node* next;
}Node;


typedef struct stack{
  int qtd;
  Node* top;
}Stack;

And these functions:

Stack newStack(void){
  Stack tmp;
  tmp.qtd = 0;
  tmp.top = NULL;
  return tmp;
}

void push(Stack s, int value){
  if( s.qtd == 0 ){
    s.top->value = value; 
    s.qtd++;
  }
  else{
    Node* tmp = (Node*) malloc(sizeof(Node*));
    tmp->value = value;
    tmp->next = s.top;
    s.top = tmp; 
    s.qtd++;
  }
}

In the main() function I "initialize" a stack (Stack s = newStack();) and call the push function using (s,6) as parameters. I get a seg fault at s.top->value = value;. What's wrong?

3 个答案:

答案 0 :(得分:2)

You've just constructed the Stack s so s.top is NULL. Then you do this:

s.top->value = value;

Dereferencing a null pointer is undefined behavior. You're lucky all you got was a segfault.

答案 1 :(得分:2)

In addition to the things already mentioned, you should also check the return value of malloc, so

Node* tmp = (Node*) malloc(sizeof(Node));
if (tmp == NULL)
{
    return; 
}

as malloc is not guaranteed to succeed, this is especially concerning when you work on devices with low memory.

答案 2 :(得分:1)

You were seeing segfault because top was initialized to NULL and then been dereferenced. Because you are implementing a stack, so every element got pushed onto the top, there is no need to check if it's empty or not in the push function.

Another problem, when allocating Node, it should be sizeof(Node), you are just allocating a pointer, not a struct.

Also, you should pass Stack as a pointer to your stack, rather than the struct itself, because what you get inside the push function is a copy of the struct, so updating its field will not update the original structure.

Try this push function:

void push(Stack *s, int value) {
    Node* tmp = (Node*) malloc(sizeof(Node));
    tmp->value = value;
    tmp->next = s->top;
    s->top = tmp;
    s->qtd++;
}

and allocate the stack by:

Stack* newStack(void) {
    Stack *s = malloc(sizeof(Stack));
    s->qtd = 0;
    s->top = NULL;
    return s;
}