链表析构函数 C++
Linked list destructor C++
我正在学习使用链表实现 Stack。这是节点 class:
class StudentInfo {
public:
string id, name, course;
double GPA;
StudentInfo *next;
};
这是堆栈 class:
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
个 自动存储期限 的对象调用了未定义行为。
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
在其链表详细信息中的所有指针,在销毁时......永远不要在指针上调用 delete
到不是使用 new
.
创建的对象
一些补充说明:
void main()
在 C++ 中是非法的。您使用的是较旧的编译器吗? ..
- 每个对象都应该管理它的资源。例如,
std::forward_list
使用分配器在内部管理其节点的分配。我建议你重新设计 StackLinkedList
以在内部管理它的节点,这样客户端就永远不会为生命周期而烦恼。
- 您应该阅读 Rule of Three, and The Rule of Five
- 你的代码中还有其他一些错误,我没有触及。
对于初学者,您不会初始化 StudentInfo
.
类型对象的数据成员 next
所以所有依赖于列表中最后一个节点等于 nullptr
的代码将调用未定义的行为。
此外,您不能对不是使用 operator new 创建的对象使用 operator 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
是一个聚合。如果 class 有一个构造函数然后声明它像
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", "computer science", 4.0, nullptr};
StudentInfo *s2 = new StudentInfo {"abc", "123", "software engineer", 4.0, nullptr };
StudentInfo *s3 = new StudentInfo {"zxc", "123", "business management", 4.0, nullptr };
然后
list.push(s1);
list.push(s2);
list.push(s3);
我正在学习使用链表实现 Stack。这是节点 class:
class StudentInfo {
public:
string id, name, course;
double GPA;
StudentInfo *next;
};
这是堆栈 class:
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
个 自动存储期限 的对象调用了未定义行为。
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
在其链表详细信息中的所有指针,在销毁时......永远不要在指针上调用 delete
到不是使用 new
.
一些补充说明:
void main()
在 C++ 中是非法的。您使用的是较旧的编译器吗? ..- 每个对象都应该管理它的资源。例如,
std::forward_list
使用分配器在内部管理其节点的分配。我建议你重新设计StackLinkedList
以在内部管理它的节点,这样客户端就永远不会为生命周期而烦恼。 - 您应该阅读 Rule of Three, and The Rule of Five
- 你的代码中还有其他一些错误,我没有触及。
对于初学者,您不会初始化 StudentInfo
.
next
所以所有依赖于列表中最后一个节点等于 nullptr
的代码将调用未定义的行为。
此外,您不能对不是使用 operator new 创建的对象使用 operator 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
是一个聚合。如果 class 有一个构造函数然后声明它像
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", "computer science", 4.0, nullptr}; StudentInfo *s2 = new StudentInfo {"abc", "123", "software engineer", 4.0, nullptr }; StudentInfo *s3 = new StudentInfo {"zxc", "123", "business management", 4.0, nullptr };
然后
list.push(s1);
list.push(s2);
list.push(s3);