c-为什么在构建二叉树时会出现分段



我通过gdb发现这段代码中的这一行是seg错误。然而,我似乎不明白为什么?在seg故障发生之前,它将运行6/7次。Temp是包含频率(int)的链表中的一个节点,我用它在升序链表中查找位置以插入新节点。

while (ind == 0 && temp != NULL)
{
    temp = temp -> next;
    if (temp -> frequency > parent_node -> frequency) /*<--- SEG FAULT HERE */
    {
        parent_node -> next = temp -> next; /* parent points at higher freq node */ 
        temp -> next = parent_node; /* parent node is temp next */
        ind = 1;
    }
    if (temp -> next == NULL)
    {
        temp -> next = parent_node; 
        ind = 1;          
    }
}

您执行temp = temp->next,但temp->next可能是nullptr。在尝试访问它的memebers之前,必须检查它是否为null。

以下是一些代码,它将把newnode指向的新节点插入到链表中,其中liststart指向列表中的第一个节点,或者对于空列表是NULL

if (liststart == NULL) {
    liststart = newnode;
    newnode->next = NULL;
} else {
    struct mylist *prev = liststart;
    while (prev->next != NULL && prev->next->frequency <= newnode->frequency) {
        prev = prev->next;
    }
    if (prev->next == NULL) {
        prev->next == newnode;
        newnode->next = NULL;
    } else {
        newnode->next = prev->next->next;
        prev->next = newnode;
    }
}

这里有一个使用指针对指针的替代版本:

struct mylist **pprev;
pprev = &liststart;
while (*pprev != NULL && (*pprev)->frequency <= newnode->frequency) {
    pprev = &(*pprev)->next;
}
newnode->next = *pprev;
*pprev = newnode;

您的问题是检查temp是否为null,然后立即更新temp,因此它可能再次为null。

(我不喜欢temp这个名字,所以在我的例子中我把它改成了node

如果你分解它,它是最清晰的,所以:

while(ind == 0 && node != null) {
     node = node -> next;  // now node might be null
     doStuffWith(node);
}

相反,您可以将赋值移动到循环的末尾。当然,这意味着第一次任务没有发生。因此,您可能需要在循环外调用它一次:

node = node -> next; // or some other initialisation of node
while(ind == 0 && node != null) {
     doStuffWith(node);
     node = node -> next;
}

也许你已经被告知了DRY原则:"不要重复自己",所以你可能会对重复node = node -> next感到不舒服。然而,这是一个非常常见的模式的例子,例如:

int chars = stream.read(buffer);
while(chars != -1) {
     doSomethingWith(buffer);
     chars = stream.read(buffer);
}

相关内容

  • 没有找到相关文章

最新更新