首页 > 解决方案 > 我的程序出现分段错误,但它在我实现多态性之前运行

问题描述

这是我的程序,可让您将学生或教职员工添加到列表中。每当调用函数 addHead() 和 addTail() 时,程序都会在第 307 行或第 325 行之后崩溃

这是基类

class Person
 {
    private:
        string name, title, department;
    public:
        Person *next, *prev;
        // Constructor & Destructor
        Person()
        {
            name = "";
            title = "";
            department = "";
        }

        Person(string nName, string nTitle, string nDepartment)
        {
            name = nName;
            title = nTitle;
            department = nDepartment;
        }

        ~Person(){};

        // Setters
        void setName(string nName)
        {
            name = nName;
        }

        void setTitle(string nTitle)
        {
            title = nTitle;
        }
        void setDepartment(string nDepartment)
        {
            department = nDepartment;
        }

        // get-ers
        string getName()
        {
            return name;
        }

        string getTitle()
        {
            return title;
        }

        string getDepartment()
        {
            return department;
        }

        virtual void printAll()
        {
            printf("%s is a %s in the %s department \n", name.data(), title.data(), department.data());
        }

};

这是 2 派生类

class Student: public Person{
    private:
        struct Date gradDay;
        string minor, extraC;

    public:
    
        Student(string nName, string nTitle, string nDepartment, int m, int d, int y, string nMinor, string nExtraC)
            : Person(nName,nTitle,nDepartment)
        {
            gradDay.month = m;
            gradDay.day = d;
            gradDay.year = y;
            minor = nMinor;
            extraC = nExtraC;
        }
        ~Student(){};

        // Setters
        void setDate(int m, int d, int y)
        {
            gradDay.month = m;
            gradDay.day = d;
            gradDay.year = y;
        }

        void setMinor(string nMinor)
        {
            minor = nMinor;
        }

        void setExtraC(string nExtraC)
        {
            extraC = nExtraC;
        }

        // Getters
        Date getDate()
        {
            return gradDay;
        }

        string getMinor()
        {
            return minor;
        }

        string getExtraC()
        {
            return extraC;
        }

        // This function finds the number of months until graduation
        int monthTilGrad(int month, int year)
        {
            int x = month + year*12;
            int y = gradDay.month + gradDay.year*12;

            return y - x;
        }

        void printAll()
        {
            Person::printAll();
            printf("     They minor in %s and will graduate on %d/%d/%d. \n     Extracurricular Activities: %s\n",minor.data(), gradDay.month, gradDay.day, gradDay.year, extraC.data());
        }

};

class Faculty: public Person{
    private:
        Date startDate;
    public:
        Faculty(string nName, string nTitle, string nDepartment, int m, int d, int y)
            : Person(nName,nTitle,nDepartment)
        {
            startDate.month = m;
            startDate.day = d;
            startDate.year = y;
        }

        ~Faculty(){};

        // Setters
        void setStartDate(int m, int d, int y)
        {
            startDate.month = m;
            startDate.day = d;
            startDate.year = y;
        }
        
        // Getters
        Date getStartDate(){
            return startDate;
        }

        void printAll()
        {   
            Person::printAll();
            printf("     They started working here on %d/%d/%d\n", startDate.month, startDate.day, startDate.year);
        }
};

这是我做的清单

class list_c{
    protected:
        Person *Head, *Tail;
    public:
        void addHead(string nName, string nTitle, string nDepartment, int m, int d, int y, string nMinor, string nExtraC);
        void addTail(string nName, string nTitle, string nDepartment, int m, int d, int y);
        void remove(string name);
        void deleteAll();
        void search(string name);
        void printAll();
};

这两个功能是有问题的。他们假设在双向链表的头部添加一个新的学生对象,在列表的尾部添加一个教师对象


void list_c::addHead(string nName, string nTitle, string nDepartment, int m, int d, int y, string nMinor, string nExtraC)
{     
    cout<<"in addHead()\n";
    Person *newStudent = new Student(nName,nTitle,nDepartment,m,d,y,nMinor,nExtraC);

    cout<<"before iff\n";
    if(Head)
    {
        Head = newStudent;

    } else{
        cout << "in else\n";
        Head->prev = newStudent;
        newStudent->next = Head;
        Head = newStudent;
        Head->prev = NULL;
        cout << "end of else\n";
    }

    cout<<"exiting addHead()...\n";
}

void list_c::addTail(string nName, string nTitle, string nDepartment,int m, int d, int y)
{   
    Person *newPerson = new Faculty(nName,nTitle,nDepartment,m,d,y);
    if(Tail == NULL)
    {
        Tail = newPerson;

    } else{
        Tail->next = newPerson;
        newPerson->prev = Tail;
        Tail = newPerson;
        Tail->next = NULL;
    }
}

先谢谢大家了!!

标签: c++listpolymorphism

解决方案


问题出在这部分:

if(Head)
{
    Head = newStudent;

} else{
    cout << "in else\n";
    Head->prev = newStudent;
    newStudent->next = Head;
    Head = newStudent;
    Head->prev = NULL;
    cout << "end of else\n";
}

问题是您颠倒了条件:如果您一个Head节点,则将其替换为newStudent. 如果没有节点Head,则添加newStudent到列表中。

并且在else分支中,Head指针将是一个空指针,任何对它的取消引用都会导致未定义的行为并可能崩溃。

条件应该是:

if (Head == nullptr)

请注意,这需要一个将和指针list_c初始化为空指针的构造函数。HeadTail

另请注意,当列表为空时,该addHead函数也需要更新Tail(并且该addTail函数应该对 执行相同的操作Head)。


推荐阅读