c++ - 我的程序出现分段错误,但它在我实现多态性之前运行
问题描述
这是我的程序,可让您将学生或教职员工添加到列表中。每当调用函数 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;
}
}
先谢谢大家了!!
解决方案
问题出在这部分:
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
初始化为空指针的构造函数。Head
Tail
另请注意,当列表为空时,该addHead
函数也需要更新Tail
(并且该addTail
函数应该对 执行相同的操作Head
)。
推荐阅读
- javascript - 从表单发布复杂数据。JS ==> ASP.NET MVC 5
- c++ - 为什么 cv:: Mat 对象在调试和发布之间表现不同?
- mysql - SQL 错误 1364 代码:'ER_NO_DEFAULT_FOR_FIELD',
- c++ - 了解 std::pmr::new_delete_resource
- java - Windows 服务器的 Java sftp 文件传输
- xslt - 如何使用 XSL 1.0 在重复上下文中显示当前日期?
- sql - 如何从 2 个连接表中检索数据 - 帐户和别名?
- google-sheets - 当被比较的单元格是日期时,查询中的日期比较不匹配,但如果将单元格制成文本则有效
- java - 如何将 .nfo 文件转换为 .fff
- php - 带有 foreach 的 PHP 数组