C语言 分段错误-链接列表

ego6inou  于 2023-01-12  发布在  其他
关注(0)|答案(5)|浏览(117)

我正在学习如何在 C 中构建链表。我的程序编译了,但由于某种原因我无法理解,我遇到了一个 * 分段错误 *。我已经尝试了一段时间来找出这个问题,但我没有任何运气。以下是错误代码:

int len()
{
    struct list * current = head;
    int length = 0; 

    while (current != NULL)
    {
        length++;
        current = current -> next; //move to next node
    }
    return length; 
}

struct list * search ( int key)
{
    struct list * current = head;

    while (current != NULL && current->data != key)
        current = current -> next;

    if (current != NULL && current -> data == key)
        return current;
    return NULL;
}


/* Insert a new data element with key d into the end of the list. */
void insert(int d )  //  at the end
{
    struct list * current = head; 
    struct list * new;
    while (current -> next != NULL)
        current = current -> next;
    new = (struct list *)malloc(sizeof(struct list));
    new -> data = d; 
    current -> next = new;
    new -> next = NULL;     
}

void insertAfter(int d, int where )  //  insert at the middle
{
    struct list * marker = head;
    struct list * new;

    while(marker -> data != where)
        marker = marker -> next;
    new = (struct list*)malloc(sizeof(struct list));

    new -> next = marker -> next; 
    marker -> next = new;
    new -> data = d; 
}

/* Remove the node with value d from the list */
/* assume no duplicated keys in the list */
/* If the list is empty, call prtError() to display an error message and return -1. */

void delete(int d)
{
    struct list * current1 = head; 
    struct list * current2;

    if (len() == 0)
    { //prtError("empty");
        exit(0);
    }
    if (head -> data == d)
    { 
        head = head -> next;
    }

    //Check if last node contains element
    while (current1->next->next != NULL)
        current1 = current1->next;

    if(current1->next->data == d)
            current1->next == NULL; 

    current1 = head; //move current1 back to front */

    while(current1 -> next -> data != d)
        current1 = current1 -> next; 

    current2 = current1 -> next;
    current1 -> next = current2 -> next; 

}

我在delete方法的以下行中遇到了 * 分段错误 *:

while(current1 -> next -> data != d)

为什么这是错的?

xqk2d5yq

xqk2d5yq1#

insert中,您有几个问题:

while (current -> next != NULL)

您没有检查current是否为NULLdelete中存在类似问题:

if (head -> data == d)

您需要在此处选中head,然后:

while (current1->next->next != NULL)

也是一个问题。

hlswsv35

hlswsv352#

insert after中有一个错误,因为您将溢出未找到元素的列表末尾。

7xzttuei

7xzttuei3#

您发布的代码有很多问题,但是您在评论中提到您关心insert()。它崩溃的原因是,如果在调用insert()head为NULL,您将取消引用NULL指针。
head为NULL时,您需要在其中插入一个特殊情况:

if (head) {
    while (current -> next != NULL)
        current = current -> next;
}
new = (struct list *)malloc(sizeof(struct list));
new -> data = d;
if (current) {
    current -> next = new;
} else {
    head = new;
}
new -> next = NULL;

您应该检查其他函数中的类似问题。使用search()函数作为避免在循环中解引用NULL指针的示例。

new9mtju

new9mtju4#

insert中,

while(current->next != NULL) current = current->next;

这将保证current == NULL .

current->next = new;

每次都撞到。

rkttyhzu

rkttyhzu5#

可能在insertAfter中:

while(marker -> data != where)
    marker = marker -> next;

如果没有找到具有data == where的节点,则marker将是NULL指针。
NULL指针将在后面的代码中取消引用:

new = marker -> next;

它产生segfault。检查marker->next != NULL是否应避免:

while(marker->next != NULL && marker -> data != where)
    marker = marker -> next;

但是您应该尝试使用调试符号(-g选项)编译程序,并在像GDB这样的调试器中逐行运行它。

相关问题