传递引用导致分段错误

Pass reference causing Segmentation fault

我正在尝试创建一个循环 link 列表。当我尝试通过将头指针作为引用传递来添加元素时,它会引发分段错误。我注意到,只要我调用添加元素函数,头指针的值就会发生变化。 代码片段:

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

int c = 1;
typedef struct Node node;
//node *head = NULL, *temp, *temp2, *z;
node *InitQueue(node *);
node *AddQueue(node *, int);
void DelQueue();
void display(node *);

void main()
{
    int ch;
    node *head = NULL;

    do {
        printf("1.Creation Q\n");
        printf("2.Insert element to Q\n");
        printf("3.Delete element\n");
        printf("4.Display Q\n");
        printf("5.Exit\n");
        printf("Enter your choice:\n");

        scanf("%d", &ch);
        switch (ch) {
        case 1:
            head = InitQueue(&head);
            printf("%d %p\n", head->data, head->next);
            break;

        case 2:
            printf("%d %p\n", head->data, head);
            int item;
            printf("Enter item\n");
            scanf("%d", &item);
            head = AddQueue(&head, item);
            break;

        case 3:
            DelQueue();
            break;

        case 4:
            display(&head);
            break;

        case 5:
            exit(0);
        }

    } while (ch != 5);

}

node *InitQueue(node * head)
{
    node *temp;
    temp = (node *) malloc(sizeof(node));
    printf("%p \n", temp);
    temp->next = temp;
    head = temp;
    printf("%p \n", head->next);
    return head;
}

node *AddQueue(node * head, int item)
{
    //InitQueue(&head);
    printf("%d %p\n", head->data, head);
    node *temp, *temp2;
    temp = head;
    temp2 = (node *) malloc(sizeof(node));
    //printf("Enter the data: \n");
    //scanf("%d", &temp2->data);
    temp2->data = item;

    while (temp->next != head) {
        temp = temp->next;
    }
    temp->next = temp2;
    temp->next = head;
    head = temp2;
    return head;
}

你的问题是你将变量 head 的实际内存地址传递给你的 InitQueueAddQueue 函数( 这样你就可以修改它在函数 ) 中,但它们被声明为:

node *InitQueue(node *);
node *AddQueue(node *, int);

你的函数期望 node * 而你通过了 node **

当你这样做时:

head = InitQueue(&head);
...
AddQueue(&head, item);
    1. 类型错误。你的编译器抱怨它而你忽略了
    1. InitQueue 之所以有效,是因为您正在 return 做某事。
    1. AddQueue 不起作用,因为它期望 pointer to node,而不是 pointer to pointer to node

你应该这样做:

void InitQueue(node **head)
{
    (*head) = malloc(sizeof(node));
    if (!(*head)) { /* error check */ }
    (*head)->next = (*head);
}

现在您可以像调用它一样调用它,但不需要 return 任何东西。

InitQueue(&head);

你可以用同样的方法修复AddQueue


可能感兴趣

  • Do I cast the result of malloc?
  • What are the barriers to understanding pointers and what can be done to overcome them?
  • Pointers to Pointers

关于这个功能,举例说明操作方法:

node *InitQueue(node * head)
{
    node *temp;
    temp = (node *) malloc(sizeof(node));
    printf("%p \n", temp);
    temp->next = temp;
    head = temp;
    printf("%p \n", head->next);
    return head;
}

使用它来初始化具有第一个条目的链表存在一些问题。

建议:

//node *InitQueue(node * head) // passing 'head' here is useless
node *InitQueue( int data ) // use 'data' to fill in field on first node
{
    node *temp = NULL;

    // always check the returned value from malloc 
    // to assure the operation was successful
    // if not successful, handle the error
    if( NULL == (temp = malloc(sizeof(node)) ) )
    { // then malloc failed
        perror( "malloc for initial node failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    //printf("%p \n", temp);  // debug statement

    temp->data = data;
    temp->next = NULL;    // always set the 'link' to NULL so end of list can be found

    //head = temp;    // head is a copy on the stack, so has no effect on callers 'head'

    //printf("%p \n", head->next); // debug statement

    //return head;  // this is not set to point to the malloc'd node
    return temp;
}