C语言问题:为什么我的全局变量没有更新?

3

今天我感到无聊,决定重新启动我的C语言技能,但我无法解释这个问题:

typedef struct Node
{
   struct Node* prev;
   struct Node* next;
   void* data;
} Node_t;

Node_t* head = NULL;

void add(Node_t* head, void* data)
{
   Node_t* newNode = (Node_t*)malloc(sizeof(Node_t));
   Node_t* iterate = head;

   newNode->next = newNode->prev = NULL;
   newNode->data = data;
   if(head == NULL)
   {
   /*printf("Check 0 %x\r\n", newNode);*/
      head = (Node_t*)malloc(sizeof(Node_t));
      head->next = head->prev = NULL;
      head->data = data;
      printf("Check 0.5 %x\r\n", newNode);
   }
   else
   {
      while(iterate->next != NULL)
      {
         iterate = iterate->next;
      }
      iterate->next = newNode;
      newNode->prev = iterate;
   }
}

int main(int argc, char** argv)
{
   int addValue = 0;
   int* printMe = 0;
   Node_t* iterate;

   for(addValue = 0; addValue < 10; addValue++)
   {
      add(head, &addValue);
      printf("Check 1 %x\r\n", head);
   }

printf语句打印了我指向的内存位置。每次从Add()函数调用时,它会打印一些合理的内存位置,但是一旦返回,它就会打印0(NULL)作为指针的值。这两个打印语句紧挨着。那么为什么C在Add()函数中更新了我的全局指针,但在函数调用结束后将其恢复呢?

3个回答

4

当您调用add函数时,您是通过值传递节点指针head的。您需要传递一个指向节点指针head指针。因此,为了使修改作用于全局变量,您需要传递&head而不是head

请进行以下更改:

void add(Node_t** head, void* data)

无论何时在 add 中引用 head,你都需要使用 *head 而不是 head
以以下方式调用 add:
add(&head, &addValue);

谢谢,我刚刚发现我正在查看全局变量的副本,而全局指针本身并没有被设置。 - Akron
非常好的答案,但进一步看问题让我感到困惑 - 如果这是在添加到列表中,就像它看起来那样,那么确实head不应该改变,因此问题本身存在错误。 - Stephen P
@Stephen 当你添加第一个节点时,需要将其分配给“head”。 - David Heffernan
1
另外,我认为这里一半的困惑来自于我在使用同一个名称作为本地变量和全局变量。这绝对需要改变。 - Akron
@David - 我刚意识到这是需要修改头部的情况... 在 C 中我不是这样做的 -- 我可能会写 LIST_HANDLE mylist = list_new() 然后 mylist->add(data) (这就是为什么我一开始很难理解 OOP 的区别)。 - Stephen P

1

你本地的head遮蔽了全局的head。考虑这个简化的片段:

int head;
void add(int head) {
    head = 7;  // analog to head=malloc() in your case
    printf("head=%d\n", head);
}
int main() {
    add(head);
    printf("head=%d\n", head);
    return 0;
}

从这个简单的例子中可以看出,在add中更新局部变量head对全局变量head没有任何影响。


0
我对C语言也有些生疏,但如果我正确地读取变量,你没有分配全局变量head,而是只传递指针的位置(null)。在您的过程中,head变量的范围严格限于该过程,并且在add过程中更改该值不会更改全局值。我相信如果您传递&head,您将获得所需的效果。
for(addValue = 0; addValue < 10; addValue++)
{
  add(&head, &addValue);
  printf("Check 1 %x\r\n", head);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接