Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么删除函数在C中给出链表错误_C_Loops_If Statement_Linked List_Structure - Fatal编程技术网

为什么删除函数在C中给出链表错误

为什么删除函数在C中给出链表错误,c,loops,if-statement,linked-list,structure,C,Loops,If Statement,Linked List,Structure,我目前正在开发一个基于链表的程序。但是我的delete函数会导致程序崩溃。我想允许用户根据航班号删除航班。但我不知道是什么导致了车祸。如何解决这个问题?谢谢 struct flight { int number; char source[20]; char destination[20]; struct flight* next; }; void enter(); void display(); void delete(); int count(); typ

我目前正在开发一个基于链表的程序。但是我的delete函数会导致程序崩溃。我想允许用户根据航班号删除航班。但我不知道是什么导致了车祸。如何解决这个问题?谢谢

struct flight {
    int number;
    char source[20];
    char destination[20]; 
    struct flight* next;
};

void enter();
void display();
void delete();
int count();

typedef struct flight NODE;

NODE* head_node, * first_node, * temp_node = 0, * prev_node, next_node;
int data;
char data2[20], data3[20];

您可能正在delete函数中创建一个额外的循环。您应该检查是否正在删除不属于链接列表的节点。

您可能正在删除函数中进行额外的循环。您应该检查是否正在删除不属于链接列表的节点。

简短回答:避免使用全局变量

在delete函数中,设置全局变量temp_节点的值

然后调用函数count。在count中,还使用全局变量temp_节点。您可以更改它,直到其值为NULL

然后回到delete函数,执行以下操作:

temp_node = temp_node->next;
取消对空指针的引用!这真的很糟糕,会使你的程序崩溃

所以首先:去掉所有的全局变量

例如,计数函数应为:

int count(NODE* p)
{
    int count = 0;
    while (p != NULL) {
        count++;
        p = p->next;
    }
    return count;
}
并将其命名为:counter=countfirst\u节点

您的删除功能可能如下所示:

NODE* delete(NODE* first_node) { ... }
也就是说

删除函数中的原则是错误的。您不需要计算节点的数量。只需迭代直到到达终点,即next为NULL

进一步-为什么在delete函数中使用malloc内存?为什么要在malloc之后覆盖指针?那么你有内存泄漏

temp_node = (NODE*)malloc(sizeof(NODE));  // WHY??
temp_node = first_node;  // UPS... temp_node assigned new value.
                         // So malloc'ed memory is lost.
现在-找到匹配节点时会发生什么情况:

    if (flightno == data) {
        temp_node = temp_node->next;
        first_node = temp_node;       // UPS.. first_node changed
        printf("\nFlight log deleted.\n");
    }
然后更改第一个节点。因此,当前节点之前的所有节点都将丢失!那不是你想要的。仅当匹配位于链接列表的第一个节点上时,才需要更改第一个节点

那么:对于j=0;j表示j=0;j<计数器;但正如我之前所说的。。。不要使用这种循环

使用类似于:

while (temp_node != NULL) 
{
    ...
    temp_node = temp_node->next;
}
顺便问一下:为什么你要在每个循环中打印出来?将负片打印移到循环外

删除功能可以通过多种方式实现。下面的示例不是最紧凑的实现,但它很容易理解

NODE* delete(NODE* head, int value_to_match)
{
    NODE* p = head;
    if (p == NULL) return NULL;

    // Check first node
    if (p->data == value_to_match)
    {
        // Delete first node
        head = head->next;   // Update head to point to next node
        free(p);             // Free (aka delete) the node
        return head;         // Return the new head
    }

    NODE* prev = p;          // prev is a pointer to the node before
    p = p->next;             // the node that p points to

    // Check remaining nodes
    while(p != NULL)
    {
        if (p->data == value_to_match)
        {
            prev->next = p->next; // Take the node that p points to out
                                  // of the list, i.e. make the node before
                                  // point to the node after
            free(p);              // Free (aka delete) the node
            return head;          // Return head (unchanged)
        }

        prev = p;                 // Move prev and p forward 
        p = p->next;              // in the list
    };

    return head;  // Return head (unchanged)
}
把它叫做:

head = delete(head, SOME_VALUE);
简短回答:避免全局变量

在delete函数中,设置全局变量temp_节点的值

然后调用函数count。在count中,还使用全局变量temp_节点。您可以更改它,直到其值为NULL

然后回到delete函数,执行以下操作:

temp_node = temp_node->next;
取消对空指针的引用!这真的很糟糕,会使你的程序崩溃

所以首先:去掉所有的全局变量

例如,计数函数应为:

int count(NODE* p)
{
    int count = 0;
    while (p != NULL) {
        count++;
        p = p->next;
    }
    return count;
}
并将其命名为:counter=countfirst\u节点

您的删除功能可能如下所示:

NODE* delete(NODE* first_node) { ... }
也就是说

删除函数中的原则是错误的。您不需要计算节点的数量。只需迭代直到到达终点,即next为NULL

进一步-为什么在delete函数中使用malloc内存?为什么要在malloc之后覆盖指针?那么你有内存泄漏

temp_node = (NODE*)malloc(sizeof(NODE));  // WHY??
temp_node = first_node;  // UPS... temp_node assigned new value.
                         // So malloc'ed memory is lost.
现在-找到匹配节点时会发生什么情况:

    if (flightno == data) {
        temp_node = temp_node->next;
        first_node = temp_node;       // UPS.. first_node changed
        printf("\nFlight log deleted.\n");
    }
然后更改第一个节点。因此,当前节点之前的所有节点都将丢失!那不是你想要的。仅当匹配位于链接列表的第一个节点上时,才需要更改第一个节点

那么:对于j=0;j表示j=0;j<计数器;但正如我之前所说的。。。不要使用这种循环

使用类似于:

while (temp_node != NULL) 
{
    ...
    temp_node = temp_node->next;
}
顺便问一下:为什么你要在每个循环中打印出来?将负片打印移到循环外

删除功能可以通过多种方式实现。下面的示例不是最紧凑的实现,但它很容易理解

NODE* delete(NODE* head, int value_to_match)
{
    NODE* p = head;
    if (p == NULL) return NULL;

    // Check first node
    if (p->data == value_to_match)
    {
        // Delete first node
        head = head->next;   // Update head to point to next node
        free(p);             // Free (aka delete) the node
        return head;         // Return the new head
    }

    NODE* prev = p;          // prev is a pointer to the node before
    p = p->next;             // the node that p points to

    // Check remaining nodes
    while(p != NULL)
    {
        if (p->data == value_to_match)
        {
            prev->next = p->next; // Take the node that p points to out
                                  // of the list, i.e. make the node before
                                  // point to the node after
            free(p);              // Free (aka delete) the node
            return head;          // Return head (unchanged)
        }

        prev = p;                 // Move prev and p forward 
        p = p->next;              // in the list
    };

    return head;  // Return head (unchanged)
}
把它叫做:

head = delete(head, SOME_VALUE);

有什么建议作为例子吗?我可以看到你在做从j=0到的循环j@R-您可能需要稍微修改一下delete函数。参考任何在线资源,您将获得删除节点功能,并根据您的需要进行匹配。如果您仍然不明白,请随意评论任何建议作为示例?我可以看到您正在进行从j=0到的循环j@R-您可能需要稍微修改一下delete函数。参考任何在线资源,您将获得删除节点功能,并根据您的需要进行匹配。如果您仍然不明白,请随时发表评论。在发布答案后,不要对您的问题进行重大更改。这些更改将使已发布的答案无效。不好的。您可以做的是编辑问题,并在第一个版本下面添加代码的版本2。发布的代码无法编译!首先,因为它缺少所需头文件所需的include语句。您是否希望我们猜测您的代码实际包含哪些头文件?发布答案后,不要对您的问题进行重大更改。这样的更改使alread无效
我张贴了答案。不好的。您可以做的是编辑问题,并在第一个版本下面添加代码的版本2。发布的代码无法编译!首先,因为它缺少所需头文件所需的include语句。您是否希望我们猜测您的代码实际包含哪些头文件?