C++ 链表析构函数C++;
我正在学习使用链表实现堆栈。这是节点类:C++ 链表析构函数C++;,c++,constructor,linked-list,aggregate,destructor,C++,Constructor,Linked List,Aggregate,Destructor,我正在学习使用链表实现堆栈。这是节点类: class StudentInfo { public: string id, name, course; double GPA; StudentInfo *next; }; 这是堆栈类: class StackLinkedList { public: StudentInfo* top; //pointer to point to the top node i
class StudentInfo {
public:
string id, name, course;
double GPA;
StudentInfo *next;
};
这是堆栈类:
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()上运行单元测试时,一切正常。但是,在调用析构函数()并显示错误后,调试断言失败…是否为_block_type_有效(header->_block_use)。调试器在delete top触发断点代码>
//destructor
~StackLinkedList() {
StudentInfo *current = top;
while (top) {
current = current->next;
delete top; //here
top = current;
}
}
如果我把top=NULL代码>之前<代码>删除顶部代码>,错误消失。因此,我对top=NULL有点困惑代码>语句。
编辑:节点类型的构造函数
StudentInfo(string id, string name, string course, double gpa) {
this->id = id; this->name = name; this->course = course; this->GPA = gpa; this->next = NULL;
}
您通过尝试删除自动存储持续时间的对象来调用未定义的行为
如您所见,s1
、s2
、s3
是自动存储持续时间的对象(即编译器在其生命周期结束时自动调用其析构函数)
然而,您将它们的地址传递给列表
,其析构函数在销毁时删除其链接列表细节中的所有指针。。。。切勿对指向未使用new
创建的对象的指针调用delete
一些补充说明:
>代码>空()/c>在C++中是非法的。您正在使用旧的编译器吗李>
- 每个对象都应该管理其资源。例如,
std::forward_list
使用分配器在内部管理其节点的分配。我建议您重新设计StackLinkedList
以在内部管理其节点,这样客户机就不会担心生命周期问题
- 你应该仔细阅读,然后
- 你的代码中还有一些其他的bug,我还没有触及
首先,您不能初始化类型为StudentInfo
的对象的数据成员next
因此,依赖于列表中最后一个节点等于nullptr
的所有代码将调用未定义的行为
此外,对于未使用“新建”操作符创建的对象,也不能使用“删除”操作符
因此,与其说是声明
StudentInfo s1("phi", "123", "computer science", 4.0);
StudentInfo s2("abc", "123", "software engineer", 4.0);
StudentInfo s3("zxc", "123", "business management", 4.0);
您至少应该编写(我假设StudentInfo
是一个聚合
StudentInfo( const string &id,
const string &name,
const string &course,
double gpa,
StudentInfo *next = nullptr )
{
this->id = id; this->name = name; this->course = course; this->GPA = gpa; this->next = next;
}
)
StudentInfo*s1=新的StudentInfo{“phi”,“123”,“计算机科学”,4.0,nullptr};
StudentInfo*s2=新的StudentInfo{“abc”,“123”,“软件工程师”,4.0,nullptr};
StudentInfo*s3=新的StudentInfo{“zxc”,“123”,“业务管理”,4.0,nullptr}
然后
list.push(s1);
list.push(s2);
list.push(s3);
建议阅读:首先,尝试运行valgrind并检查是否存在内存泄漏。1)不要使用原始new
/delete
。使用智能指针(或者只是简单的对象容器)。2) 不要使用NULL
。使用nullptr
@JesperJuhl如果我尝试为指针返回类型返回nullptr是否有效?@Phi trung您可以返回nullptr
,当然。这是否是您想要的,以及您的呼叫方期望的是另一个问题。还有一个问题,我真的不明白top=NULL
如何解决这个问题?在您的top=NULL
之后,下面的delete top
变成了“delete NULL”,这基本上是一个无操作(不调用任何dtor,不释放任何内存)@PhiTruong,如何在内部执行单元测试超出了这里的回答范围。但是,作为一个单元,StackLinkedList
,您当然会有很多测试案例……至于您的第二个评论,Gian Paolo已经解释了……我应该为nullptr
使用什么参数类型?@PhiTruong您说的是什么参数In类定义是一个集合。@ PhiTruong因为它的所有数据成员是公共的或将第五个参数与对应的数据成员对应的默认参数而删除,所以它是冗余的。谢谢,我不知道,我可以在没有构造函数的情况下在C++中启动一个对象。
list.push(s1);
list.push(s2);
list.push(s3);