我正在学习使用链表实现Stack.这是节点类:
class StudentInfo {
public:
string id, name, course;
double GPA;
StudentInfo *next;
};
这是Stack类:
class StackLinkedList {
public:
StudentInfo* top; //pointer to point to the top node
int size; //variable to keep the size of the stack
//constructor
StackLinkedList() {
this->size = 0;
this->top = NULL;
}
//destructor
~StackLinkedList() {
StudentInfo *current = top;
while (top) {
current = current->next;
delete top;
top = current;
}
}
//to add item into stack - push on top
void push(StudentInfo *newStudent) {
if (!top) {
top = newStudent;
return;
}
newStudent->next = top;
top = newStudent;
size++;
}
void main() {
StudentInfo s1("phi", "123", "computer science", 4.0);
StudentInfo s2("abc", "123", "software engineer", 4.0);
StudentInfo s3("zxc", "123", "business management", 4.0);
StackLinkedList list;
StudentInfo *ptr;
ptr = &s1;
list.push(ptr);
ptr = &s2;
list.push(ptr);
ptr = &s3;
list.push(ptr);
};
当我尝试在push()和printAll()上运行单元测试时,一切都很好.但是,在调用了析构函数()之后,出现错误Debug Assertion Failed … is_block_type_valid(header-> _block_use).并且调试器在delete top处触发了断点;
//destructor
~StackLinkedList() {
StudentInfo *current = top;
while (top) {
current = current->next;
delete top; //here
top = current;
}
}
如果我把top = NULL;在删除top;之前,错误消失了.所以,我对top = NULL有点困惑;声明.
编辑:NodeType的构造函数
StudentInfo(string id, string name, string course, double gpa) {
this->id = id; this->name = name; this->course = course; this->GPA = gpa; this->next = NULL;
}
解决方法:
您通过尝试删除自动存储持续时间的对象来调用未定义的行为.
int main() {
StudentInfo s1("phi", "123", "computer science", 4.0);
StudentInfo s2("abc", "123", "software engineer", 4.0);
StudentInfo s3("zxc", "123", "business management", 4.0);
StackLinkedList list;
StudentInfo *ptr;
ptr = &s1;
list.push(ptr);
ptr = &s2;
list.push(ptr);
ptr = &s3;
list.push(ptr);
};
如您所见,s1,s2,s3是自动存储持续时间的对象(也就是说,编译器会在其生命周期结束时自动调用它们的析构函数).
然而,你将它们的地址传递给list,它的析构函数会在破坏时删除其链表详细信息中的所有指针….永远不要在指向未使用new创建的对象的指针上调用delete.
一些额外的说明:
> void main()在C中是非法的.你使用的是较旧的编译器吗? ..
>每个对象都应该管理其资源.例如,std :: forward_list使用allocator在内部管理其节点的分配.我建议您重新设计StackLinkedList以在内部管理其节点,以便客户端永远不会打扰生命周期.
>你应该阅读Rule of Three和The Rule of Five
>您的代码中还有其他一些错误,我没有碰过.