我在学习C入门书第13.4章时遇到了一个问题,我在C中定义了两个class
类型,其中一个类包含一个set变量,它将pointers
存储到另一个类类型中,现在,我为类类型record
定义了一个destructor
,当该类类型record
的元素被析构时,destructor
会删除类的file
集合中存储的地址,但是我运行这个程序的时候,系统崩溃了,我只想知道发生了什么,非常感谢。
实际上,这是C++初级读本13.4中的一个已知问题。我编写了一个类似但更简单的代码来重现相同的错误,代码如下:
#include <iostream>
#include <memory>
#include <set>
class file;
class record {
public:
~record() {
deletefun();
}
int x;
std::set<file*> file_log;
void deletefun();
};
class file {
public:
std::set<record*> ptr_to_record;
void remove(record* e)
{
std::cout << e->x << std::endl;
ptr_to_record.erase(e);
}
};
void record::deletefun() {
for (auto i : file_log)
i->remove(this);
}
int main() {
record e1;
e1.x = 10;
file n1;
e1.file_log.insert(&n1);
}
我尝试输出类变量“file”的大小,结果是1,这意味着集合中存储了地址,但是我根本无法访问集合,甚至连开始元素都无法访问。
我的操作系统是Windows,我在Visual Studio 2022中编译了这段代码。
1条答案
按热度按时间pengsaosao1#
e1
在n1
之前创建。因此,
e1
在n1
之后被销毁。因此,当您到达
e1
的销毁时,n1
已经被销毁,并且i->remove(this);
尝试访问被销毁的对象。您需要确保所有
file
的寿命都比存储其地址的record
长。