Home > Software engineering >  generic C - what happens when I call "struct *s"?
generic C - what happens when I call "struct *s"?

Time:05-28

I'm taking CS 107 Stanford course, and in the lecture we have this simple stack struct

// stack.h
typedef struct {
  int *elems;
  int logicallen;
  int alloclen;
} stack;

he mentioned by doing

stack *s;

it should automatically reserve memory space for the struct.

However, I got a segmentation fault and I have to manually allocate memory by doing this:

stack *s = malloc(3*sizeof(int));

When I try to print s, it shows a 0

// this will cause segmentation fault
int main(){
  stack *s;
  printf("%d\n", s);
  StackNew(s); 
}
// this is fine
int main(){
  stack *s = malloc(sizeof(stack));
  printf("%d\n", s);
  StackNew(s); 
}

So what exactly does stack *s; do?

CodePudding user response:

he mentioned by doing

stack *s;

it should automatically reserve memory space for the struct.

No, it should never do that.

So what exactly does stack *s; do?

What it does however is declare a pointer to a stack. Or, in other words, reserve memory space for a pointer to stack. That pointer is not initialized, meaning it points to some random (*) memory location. And attempting to dereference it will result in undefined behaviour, which means that anything can happen, including your code seemingly working. This explains your statement:

When I try to print s, it shows a 0

It's good practice to almost always initialize your pointers to NULL prior using them. This way, you will avoid a hole category of problems.

And also, don't forget to free your allocated resources after you no longer need them.


(*) Generally, it points to wherever it was pointing to the last time it was used.

CodePudding user response:

This line

stack *s;

is a declaration (definition) within the function main of an uninitialized pointer of the type stack *. So the value of the pointer is indeterminate. Neither object of the type stack is created.

To dereference the pointer it must point to a valid object. Otherwise dereferencing of an uninitialized pointer invokes undefined behavior.

Pay attention to that to output a pointer you have to use the conversion specifier p instead of d

printf("%p\n", ( void * )s);
  • Related