通用 C - 当我调用 "struct *s" 时会发生什么?

generic C - what happens when I call "struct *s"?

我正在上斯坦福大学的 CS 107 课程,在讲座中我们有这个简单的堆栈结构

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

他提到

stack *s;

它应该自动为结构预留内存space。

但是,我遇到了分段错误,我必须通过这样做手动分配内存:

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

当我尝试打印 s 时,它显示 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); 
}

那么 stack *s; 到底是做什么的?

这一行

stack *s;

stack * 类型的未初始化指针在函数 main 中的声明(定义)。所以指针的值是不确定的。 stack 类型的对象均未创建。

要取消引用指针,它必须指向一个有效的对象。否则取消引用未初始化的指针会调用未定义的行为。

注意,要输出指针,您必须使用转换说明符 p 而不是 d

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

he mentioned by doing

stack *s;

it should automatically reserve memory space for the struct.

不,它不应该那样做。

So what exactly does stack *s; do?

然而,它所做的是声明一个指向 stack 的指针。或者,换句话说,为 指向 stack 的指针 保留内存 space。该指针未初始化,这意味着它指向某个随机 (*) 内存位置。并试图取消引用它会导致未定义的行为,这意味着任何事情都可能发生,包括您的代码看似 工作。这解释了你的陈述:

When I try to print s, it shows a 0

在使用它们之前几乎总是将指针初始化为 NULL 是一种很好的做法。这样,您将避免一类问题。

另外,不要忘记在不再需要分配的资源后释放它们。


(*) 通常,它指向上次使用时指向的位置。