C指针指针和seg错误

时间:2012-08-21 17:00:40

标签: c pointers segmentation-fault

下面是我在C中的简单链接列表。我的问题是“headRef =& newNode;”这会导致分段错误。然后我尝试了“* headRef = newNode;”这解决了seg故障问题。虽然这两行代码在我看来以同样的方式工作,但为什么会导致seg错误而另一行不会? 提前谢谢。

struct node{
  int data;
  struct node* next;
};

void Push(struct node** headRef, int data){
  struct node* newNode = malloc(sizeof(struct node));
  if(!newNode) return;
  newNode->data = data;
  newNode->next = *headRef;
  headRef = &newNode;
  return;
}

4 个答案:

答案 0 :(得分:1)

newNode已经是一个地址,您已将其声明为指针:struct node *newNode。使用*headRef = newNode,您将该地址分配给类似的指针,struct node *struct node *

令人困惑的是,headRef = &newNode 似乎同样有效,因为类型同意:您正在分配给struct node **另一个struct node **

但这有两个原因:

  1. 您想要更改函数参数headRef的值,struct node *。您已将headRef地址传递给函数,因为C是按值传递的,因此要更改变量,您需要它的地址。要更改的变量是一个地址,因此您将指针传递给指针struct node **:需要额外的间接级别,以便您可以更改地址该功能,并将该更改反映为 outide 该功能。因此,在函数中你需要取消引用变量以获得你想要改变的内容:在你的函数中,你想要改变*headRef而不是 { {1}}。
  2. headRef的地址正在创建一个不必要的间接层。如上所述,您要分配的值是 newNode所持有的地址 的地址 {{ 1}}。

答案 1 :(得分:1)

你通过指针对引用语义有一个基本的误解。以下是核心示例:

// Call site:
T x;
modify(&x);         // take address-of at the call site...

// Callee:
void modify(T * p)  // ... so the caller takes a pointer...
{
    *p = make_T();  // ... and dereferences it.
}

所以:调用者接受地址,被调用者取消引用指针并修改对象。

在您的代码中,这意味着您需要说*headRef = newNode;(在我们的基本示例中,您有T = struct node *)。你有错误的方法!

答案 2 :(得分:0)

headRef = &newNode是一个本地赋值,因此赋值仅在Push函数的范围内有效。如果headRef的更改应在Push之外显示,则需要*headRef = newNode。而且,这两者并不相同。 headRef = &newNode将节点指针的地址分配给指向节点指针的指针,而*headRef = newNode使用间接将节点的地址分配给指向节点的指针。

答案 3 :(得分:0)

您正在设置headRef以保存堆栈中存在的变量的地址;只要您的Push()函数返回,堆栈就不再有效,您可以指望它被覆盖。这是段错误的确定方法。