【问题标题】:Global linked list pointing to NULL when passed through a function通过函数传递时指向 NULL 的全局链表
【发布时间】:2013-10-30 09:01:35
【问题描述】:

我正面临这个问题,如果我通过一个函数(插入一个节点)传递一个链表(我定义为全局),一旦指针返回到主函数,我总是得到一个 NULL 值。 但是,如果我将节点添加到全局定义中,它也可以正常工作,这也是预期的。有人可以帮我解释一下为什么这段代码不起作用而且 *list 总是指向 NULL

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

    typedef struct node node;
    static node *list=NULL;

boolean add_node(node *list, int n, int val)
{

    node *temp=NULL;
    temp = (node *)malloc(sizeof(node));
    temp->val = val;
    temp->next = NULL;

    if((list==NULL) && (n!=0))
    {
        printf("link list is NULL and addition at non zero index !");
        return (FALSE);
    }

    if(list==NULL)
    {
       printf("list is NULL ");
       list= temp;
    }
    else if(n==0)
    {
       temp-> next = list;
       list=temp;
    }
    else
    {
        node *temp2;
        temp2 = list;
        int count =0;
        while(count++ != (n-1))
        {
          temp2 = temp2->next;
          if(temp2==NULL)
          {
            printf("nth index %d is more then the length of link list %d ",n,count);
            return (FALSE);
          }
        }

        node *temp3;
        temp3 = temp2->next;
        temp2-> next = temp;
        temp->next = temp3;
    }

    printf("List after node insertion \n");
    print_link_list(list);
    return (TRUE);
}

main()
{
     c= getchar();
     switch(c)
        {
            case 'I':
            {
                printf("Insert a index and value  \n");
                int index,value;
                scanf_s("%d",&index);
                scanf_s("%d",&value);
                if(add_node(list,index,value)==FALSE)
                {
                    printf("Couldn't add the node \n");
                }

                if(list==NULL)
                {
                    printf("\n After Insert op.,list is NULL, add %x",list);
                }
                else
                {
                    printf("After Inset op., list is not Null, add %x",list);
                }
            }
            break;
            case 'D':

....
}

【问题讨论】:

    标签: c pointers linked-list


    【解决方案1】:

    从不修改全局变量list,只修改参数list

    您可能希望该参数是指向指针的指针,并分配,而不是,参数。

    【讨论】:

    • 对不起,你能不能说得更具体一点。如果我们在 main 函数中修改这个列表,它将正常工作。但是当我将这个全局指针传递给某个函数时,为什么不呢?在这种情况下,我仍在传递全局指针节点 *list 的内存位置。
    • 不,您正在传递全局变量的 。也就是说,参数列表是全局变量的副本,分配给它会更改副本的值,而保持全局 list 不变。
    【解决方案2】:

    尝试更改函数定义以使用指向指针的指针:

    boolean add_node(node **list, int n, int val)
    

    您需要这样做,因为您的全局变量list 需要更新。全局是一个指针:一个地址。在您的 add_node 函数中,当您说 list = temp 时,您只是在修改本地指针(也称为列表)。当您离开该功能时,全局列表保持不变。但是,如果您将指针 传递给 该全局指针(指向指针的指针),您就可以修改 存储在原始指针中的地址

    一个例子:

    int *pGlobal = NULL;
    
    void someThing(int *pInt)
    {
        int LocalInt = 3;
        pInt = &LocalInt; // I can change where this pointer is pointing - it's just a copy
        // pGlobal remains unchanged
    }
    
    void someThingElse(int **ppInt)
    {
        // I am now modifying the ADDRESS of a pointer that we have the address of
        *ppInt = malloc(sizeof(int));
        // pGlobal has been changed to point at my allocated memory
    }
    
    void main()
    {
        // This passes a COPY of the address held in pGlobal
        someThing(pGlobal);
    
        // Here we are now passing a pointer (address) TO another pointer.
        // The pointer pGlobal does occupy some real space in memory. We are passing a
        // COPY of the value of its location so we can modify it.
        someThingElse(&pGlobal);
    }
    

    另外,为了良好的做法,不要将全局命名为与局部变量(列表)或参数相同的名称 - 它会编译但很容易导致问题/混乱/错误!

    【讨论】:

    • 谢谢。仍然想知道,传递双指针有什么帮助。使用此代码,我是否没有传递全局列表指针的内存地址。静态节点 *list=NULL;-> 假设 0xaabb 是指向 NULL 的地址。在主函数中,当我调用此函数时 (add_node(list,index,value)==FALSE) -> 第一个参数会是 0xaabb,它将指向 NULL。我的理解正确吗?
    • 没有。您正在传递指针所持有的地址,因此修改不会更改全局指针的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多