分段故障(堆芯倾倒)?它是什么,为什么会引起???(c++中的双循环链表程序)

Segmentation fault (core dumped) ? what is it and why is caused ??? ( doubly circular linked list program in c++)

本文关键字:c++ 程序 循环链表 故障 分段 它是什么 为什么      更新时间:2023-10-16

我的程序(它还不完整,但我真的很想知道我的错误):

#include <iostream.h>
using namespace std;
class dcllnode
{
private:
    int data;
    dcllnode *next;
    dcllnode *prev;
public:
    dcllnode(int ele)
    {
        data = ele;
        prev = next;
        next = prev;
    }
    friend class dcll;
};
class dcll
{
private:
    dcllnode *head;
public:
    dcll()
    {
        head = NULL;
    }
    void create();
    void inserts(int ele);
    void inserte(int ele);
    void inserta(int ele, int pos);
    void insertb(int ele, int pos);
    void dels();
    void dele();
    void dela();
    void display();
};
void dcll::create()
{
    if (head == NULL)
    {
        head = new dcllnode(0);
        cout << "list is created";
    }
    else
    {
        cout << "list has already been created";
    }
}
void dcll::inserts(int ele)
{
    if (head == NULL)
        cout << "please create the list first ";
    else
    {
        dcllnode *x;
        x = new dcllnode(ele);
        x->prev = head;
        x->next = head->next;
        (head->next)->prev = x;
        head->next = x;
        cout << "list is modified";
    }
}
void dcll::inserte(int ele)
{
    if (head == NULL)
        cout << "please create the list first ";
    else
    {
        dcllnode *x;
        x = new dcllnode(ele);
        x->next = head;
        x->prev = head->prev;
        (head->prev)->next = x;
        head->prev = x;
        cout << "list is modified";
    }
}
void dcll::dels()
{
    if (head == NULL)
        cout << "please create the list first ";
    else
    {
        dcllnode *x;
        head->next = x;
        head->next = x->next;
        (x->next)->prev = head;
        x->next = NULL;
        x->prev = NULL;
        delete(x);
        cout << "list is modified";
    }
}
void dcll::dele()
{
    if (head == NULL)
        cout << "please create the list first ";
    else
    {
        dcllnode *x;
        head->prev = x;
        head->prev = x->prev;
        (x->prev)->next = head;
        x->prev = NULL;
        x->next = NULL;
        delete(x);
        cout << "list is modified";
    }
}
void dcll::display()
{
    if (head == NULL)
        cout << "please create the list first ";
    else
    {
        dcllnode *p = head->next;
        while (p != head)
        {
            cout << "n" << p->data;
            p = p->next;
        }
    }
}
int main()
{
    dcll l1;
    l1.create();
    l1.inserte(10);
    l1.display();
    l1.inserts(20);
    return 0;
}

当我只使用create函数时,分割问题就不会发生。我想知道如何解决这些问题,以及如何避免未来出现分割错误。我们将提供任何信息和/或帮助。

使用非法指针(null或未初始化的指针,或指向未分配或非法内存的指针)时,通常会出现分段错误。

在您的情况下,很容易看出其中一个问题是什么,它在dcllnode构造函数中进行

prev = next;
next = prev;

执行这些赋值时,指针nextprev未初始化,它们的值不确定。像这样将它们相互分配并不会初始化它们,只是使它们都具有相同的不确定值。稍后,当您取消引用这些指针时,您将有未定义的行为,从而导致分段错误和崩溃。

可能应该将两个指针初始化为null:

prev = nullptr;  // or 0
next = nullptr;  // or 0

[注意:在C++中不要使用NULL,使用nullptr(首选),或者如果没有,则使用普通0。]

要完成约阿希姆的回答,在以下两个语句中:

(head->next)->prev = x;
(head->prev)->next = x;

head->next和head->prev可以是nullptr,所以在取消引用指针之前必须检查它。