c - C 代码函数中的段错误

标签 c pointers segmentation-fault

<分区>

struct Node {
    char gender;
    int turns_in_bathroom;
    struct Node *next;
};

struct Queue {
    struct Node *front, *back;
};

int QueueDeleteNext(Queue *myQueue, char value) {
Node *current_node, *previous_node;
previous_node = NULL;
int found = 0;
for (current_node = myQueue->front; current_node != NULL;
     previous_node = current_node, current_node = current_node->next) {
    if (current_node->gender == value) {
        if (previous_node == NULL) {
            myQueue->front = myQueue->back = NULL;
        }
        else {
            previous_node->next = current_node->next;
            if(previous_node->next == NULL){
                myQueue->back = previous_node;
            }
        }
        free(current_node);
        found = 1;
    }
}
return found;
}

我在线路上遇到段错误

if (current_node->gender == value) {

我这辈子都弄不明白为什么。这里发生了什么? 更不用说尽管我的调试器出现故障,代码仍会一直运行。不过,我认为有一些错误可能与此有关,我想确保我已经涵盖了所有基础。

最佳答案

貌似问题已经解决了,但是代码还是有问题:

  • 条件(previous_node == NULL) 测试当前节点是否是队列的头。在这种情况下,必须调整头部而不是前一个节点的 next,但是代码会清空整个队列而没有正确删除可能的尾随 enode。

  • 当队列中的最后一个节点被删除时,队列的后端应该更新,以便后续的推送可以附加到末尾。

最后,OP 的意图似乎是要删除具有相应值的所有节点,因为执行在第一次删除后并没有停止。因此,让我们这样做并返回已删除节点的数量:

int QueueDeleteNext(struct Queue *q, char value)
{
    struct Node *prev = NULL;
    struct Node *curr = q->front;
    int count = 0;

    while (curr) {
        if (curr->gender == value) {
            struct Node *nn = curr;

            if (prev == NULL) {
                q->front = curr->next;
            } else {
                prev->next = curr->next;
            }

            if (curr == q->back) q->back = prev;

            curr = curr->next;

            free(nn);
            count++;
        } else {
            prev = curr;
            curr = curr->next;
        }
    }

    return count;
}

主循环现在是一个 while 循环,它以不同方式处理删除和跳过节点。在这两种情况下,下一个节点都是 curr->next,但是当一个节点被删除时,prev节点保持不变!此代码还保留了队列的后面。

实现这一点的另一种方法是使用指向节点指针的指针而不是指向 prev 指针的指针。这消除了区分头节点和其他节点的需要。 nd首先是队列头部的地址,之后是前一个节点的'next字段的地址。代码通过nd`更新指向当前节点的指针:

int QueueDeleteNext(struct Queue *q, char value)
{
    struct Node **nd = &q->front;
    int count = 0;

    q->back = NULL;

    while (*nd) {
        if ((*nd)->gender == value) {
            struct Node *nn = *nd;

            (*nd) = (*nd)->next;

            free(nn);
            count++;
        } else {
            q->back = *nd;
            nd = &(*nd)->next;
        }            
    }

    return count;
}

此代码可以扩展为仅删除第一个节点或第一个 _n_nodes。

关于c - C 代码函数中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43803429/

相关文章:

c - 如果我尝试打印不在用户空间中的地址值,SIGSEGV 故障如何工作

c - 函数的参数是如何执行的?

C - 如何使我的数据结构实现同步?

C++ char 数组的动态数组

c - 使用 strtok 时出现段错误

c++ - 这是有效的内存对齐吗?如果没有,应该如何解决?

c - 为什么像这样初始化二维数组会更糟​​?

c - 如何按日期对链接列表进行排序?

c++ - 为什么指针分配的内存在函数之后仍然存在,而不是数组?

c++ - C/C++ 链表永远不为空