【问题标题】:Returning pointer to local variable sorted merge返回指向局部变量排序合并的指针
【发布时间】:2021-02-21 18:22:28
【问题描述】:

在课堂上我学会了不要返回指向局部变量的指针。在我发现的这个函数中,排序合并,它似乎返回了一个指向节点的指针。怎么会这样?

struct node *SortedMerge(struct node *a, struct node *b) { 
    struct node dummy; // a dummy first node to hang the result on
    
    struct node *tail = &dummy; // Points to the last result node --
                                // so tail->next is the place to add
                                // new nodes to the result.
    dummy.next = NULL;

    while (1) {
        if (a == NULL) { // if either list runs out, use the other list
            tail->next = b;
            break;
        } else
        if (b == NULL) {
            tail->next = a;
            break;
        }
        if (a->data <= b->data) {
            MoveNode(&(tail->next), &a);
        } else {
            MoveNode(&(tail->next), &b);
        }
        tail = tail->next;
    } //end while
    return (dummy.next);
}

void MoveNode(struct node **destRef, struct node **sourceRef) {
    struct node *newNode = *sourceRef;  // the front source node
    assert(newNode != NULL);
    *sourceRef = newNode->next;  // Advance the source pointer
    newNode->next = *destRef;    // Link the old dest off the new node
    *destRef = newNode;          // Move dest to point to the new node
}

【问题讨论】:

  • 它没有返回指向局部变量的指针。它返回dummy.next,这是一个来自调用者的指针。
  • dummy.next 是否曾经指向局部变量?在我看来它不像。
  • @Kevin 不是在函数中创建了 dummy ,这意味着它是本地的吗?
  • dummy 是本地的,如果您返回&amp;dummy,那将是一个问题。但是dummy.next是一个不指向局部变量的指针,所以可以作为返回值使用。
  • @RoshanSamarawickrema 当您返回指向局部变量的指针时,问题就来了。指针本身是本地的不是问题。

标签: c algorithm merge linked-list mergesort


【解决方案1】:

dummy 是一个局部变量是正确的,您应该担心指向该局部变量的指针不会被返回。但是请注意,返回的是dummy.next,它是一个可以指向任何东西的指针,所以它不会被强制指向任何本地的东西。

查看逻辑流程,dummy.next 最终指向NULL,与输入参数a 相关的东西,或与输入参数b 相关的东西。也就是说,返回的指针指向与参数相关的东西,而不是本地结构。

顺便说一句,该函数的作者试图通过调用本地 dummy 来帮助指出这一点。这应该意味着它不是一个 real 节点(因此是一个 dummy),它仅用作处理函数逻辑的便捷机制,而不是持久节点。

【讨论】:

    【解决方案2】:

    函数不返回指向本地对象的指针,它返回本地对象dummy.next的值,一个初始化为NULL的指针,并在第一次迭代期间设置为ab循环,取决于ab 的值以及a-&gt;datab-&gt;data 的比较,如果ab 都不是空参数。

    该函数使用 dummy 列表节点来避免第一次迭代的特殊情况。这是一个更简单的版本,它使用双指针来实现相同的目的:

    struct node *SortedMerge(struct node *a, struct node *b) {
        struct node *head = NULL;    // the head of the merged list.
        struct node **link = &head;  // pointer to the link to attach the next node to
    
        for (;;) {
            if (a == NULL) { // if either list runs out, use the other list
                *link = b;
                break;
            } else
            if (b == NULL) {
                *link = a;
                break;
            }
            if (a->data <= b->data) {
                *link = a;
                link = &a->next;
                a = a->next;
            } else {
                *link = b;
                link = &b->next;
                b = b->next;
            }
        }
        return head;
    }
    

    这是一个更长但可以说更易读的版本,没有双指针:

    struct node *SortedMerge(struct node *a, struct node *b) {
        struct node *head;    // the head of the merged list.
        struct node *tail;    // the tail node of the merged list.
    
        if (a == NULL)
            return b;
        if (b == NULL)
            return a;
        if (a->data <= b->data) {
            tail = head = a;
            a = a->next;
        } else {
            tail = head = b;
            b = b->next;
        }
        for (;;) {
            if (a == NULL) { // if either list runs out, use the other list
                tail->next = b;
                break;
            } else
            if (b == NULL) {
                tail->next = a;
                break;
            }
            if (a->data <= b->data) {
                tail = tail->next = a;
                a = a->next;
            } else {
                tail = tail->next = b;
                b = b->next;
            }
        }
        return head;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-10-25
      • 1970-01-01
      • 2014-05-14
      • 2020-10-13
      • 1970-01-01
      • 2023-04-09
      • 2013-10-03
      相关资源
      最近更新 更多