链表析构函数C++
Linked list destructor C++
我正在学习使用链表实现Stack。这是节点类:
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()上运行单元测试时,一切都很好。然而,在调用destructor()后,错误显示为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;
放在delete 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;
}
您通过尝试delete
对象的自动存储持续时间调用了Undefined Behavior。
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
,其析构函数deletes
在销毁时将其链表详细信息中的所有指针都传递给。。。。永远不要在指向不是使用new
创建的对象的指针上调用delete
。
一些附加说明:
void main()
在C++中是非法的。你在使用旧的编译器吗- 每个对象都应该管理其资源。例如,
std::forward_list
使用分配器在内部管理其节点的分配。我建议您重新设计StackLinkedList
以在内部管理其节点,这样客户端就不会为生存期而烦恼 - 你应该读一下"三条规则"answers"五条规则">
- 你的代码中还有其他一些错误,我没有碰过
对于初学者,您不能初始化类型为StudentInfo
的对象的数据成员next
。
因此,所有依赖于列表中最后一个节点等于nullptr
的代码都将调用未定义的行为。
此外,对于未使用操作符new创建的对象,也不能使用操作符delete。
因此,没有声明
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=new StudentInfo{"phi","123","计算机科学",4.0,nullptr};StudentInfo*s2=new StudentInfo{"abc","123","软件工程师",4.0,nullptr};StudentInfo*s3=new StudentInfo{"zxc","123","业务管理",4.0,nullptr};
然后
list.push(s1);
list.push(s2);
list.push(s3);
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 不命名构造函数和析构函数上的类型错误