单链表C++分段错误错误

问题描述 投票:0回答:1

为什么会出现错误:

int main(){
    lista *head, *x;
    head = nullptr;
    const int len = 3;
    int y[len] = {13, 4, 32};
    for(int i = len - 1; i >= 0; i--){
        x = new lista;
        x -> val = y[i];
        x -> next = head;
        head = x;
    }
    lista *p = head;
    // Changing lines are the next ones
    while(p->next != nullptr){
        p = p->next;
    }
    delete p;
    p = nullptr;

    print_lista(head);
    return 0;
}

但这不是:

int main(){
    lista *head, *x;
    head = nullptr;
    const int len = 3;
    int y[len] = {13, 4, 32};
    for(int i = len - 1; i >= 0; i--){
        x = new lista;
        x -> val = y[i];
        x -> next = head;
        head = x;
    }
    lista *p = head;
    // Changing lines are the next ones
    while(p->next->next != nullptr){
        p = p->next;
    }
    delete p->next ;
    p->next = nullptr;

    print_lista(head);
    return 0;
}

这样也行不通

while(p->next != nullptr){
    p = p->next;
}
p = p->next;
delete p;
p = nullptr;

这是给定的错误:

监控的命令转储核心

分段错误

这不是同一件事吗?在第一种情况下,p 是倒数第二个元素的下一个值,在第二种情况下,p 是倒数第三个元素的下一个值,因此 p->next 应该是倒数第二个元素的下一个值。 这是结构:

struct lista{
    int val;
    lista *next;
};

错误发生在“删除...;”线

为本·沃伊特编辑

为什么?如果我运行这样的测试:

lista *p = head;
while (p->next->next != nullptr){
    p = p->next;
}
cout << p->next;
lista *z = head;
while (z->next != nullptr){
    z = z->next;
}
cout << endl << z;

p和z都是0x5575909e3eb0,不是一样吗?

c++ list pointers singly-linked-list
1个回答
3
投票

问题在于,在失败的代码中,您正在释放列表中的最后一项,而不是将其从列表中删除。结果是一个包含悬空指针的列表,因此稍后遍历列表的操作具有未定义的行为。

工作代码确实将其从列表中分离出来。


为了回答你的思想实验,让我们让它变得更简单。

std::cout << head << '\n';
lista* z = head;
std::cout << z << '\n';

z = nullptr;
// now how many items are in the list?
std::cout << head << '\n';
std::cout << z << '\n';

// are `head` and `z` really equivalent?
z = head;
head = nullptr;
// now how many items are in the list?
std::cout << head << '\n';
std::cout << z << '\n';
© www.soinside.com 2019 - 2024. All rights reserved.