【发布时间】:2012-04-04 11:11:39
【问题描述】:
最近开始学习qt,一直在玩,也想起了一点c++,因为好久没用了……
不管怎样,我做了这个简单的测试类来看看当你有一个悬空指针时会发生什么:
#include <QtCore/QCoreApplication>
#include <iostream>
class Test{
public:
QString str;
int i;
public:
Test(){
i=1337;
str="str";
std::cout<<"initialized\n";
}
~Test(){
std::cout<<"destructor called\n";
delete &str;
delete &i;
/*the program MAY run if the deletes aren't called;*/
}
};
Test* p;
void test_function(){
Test a;
p=&a; //this will give a segfault, since the destructor of a is called at the end of this function's scope, but p still points to a
//p=new Test(a); //this will call the copy constructor of p, copying the values from a to p
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
test_function();
std::cout<<p->str.toStdString() << p->i<<std::endl;
return a.exec();
}
果然,它崩溃了(但它没有说明原因 - 可能是段错误)。但是,如果我注释了调用悬空指针的行(main() 中的 cout),程序现在会崩溃,给我一个“std::bad_alloc”异常。以下独立测试的事物列表导致不再抛出异常:
- 注释str的初始化;
- 评论str的析构函数;
- 用 std::string 替换 QString;
我尝试过但没有任何效果的是用 QString::fromStdString("str") 初始化 str(而不仅仅是 "str")。
我还尝试使用 try/catch 块围绕 str(同时是 QString)的初始化和销毁,但无济于事。此外,尝试/捕获 test_function() - 没有结果。然而,我确实通过在 try/catch 块中包围 a.exec() 成功地捕获了异常。
为什么当 cout 被注释时它会抛出异常,但否则只会崩溃? 为什么同时拥有 str 的初始化器和析构器会引发异常,但评论一个或两个只会导致崩溃? (现在我正在写这篇文章,我意识到这可能是唯一的问题;但是,为什么它会崩溃 QString 而不是 std::string?) 为什么 a.exec() 会抛出异常?
比我更了解 qt(甚至 c++)的人能否解释一下发生了什么? 谢谢
【问题讨论】:
-
不要想太多。通常,如果您发现自己在编写析构函数,则说明您做错了。
-
您将通过清理您不打算犯的错误并重试来了解更多信息。我仍然无法准确说出您要测试的内容。
-
@tmpearce:好吧,我试图在一个简单的程序中测试析构函数,看看它们何时被调用,删除是否真的删除了数据等;不知何故,我在 main() 中结束了对 cout 的评论,我得到了一个异常而不是崩溃。从那里开始,我开始使用它,看看是什么导致了异常,什么没有......
-
我明白,我不是在批评 - 试图理解你的代码是一件好事 - 但试图理解“未定义的行为”是愚蠢的差事。我建议阅读stackoverflow.com/q/2397984/1214731
-
谢谢!一本好书,我想我以前还没有真正偶然发现过这些东西。很高兴知道:)
标签: c++ qt segmentation-fault destructor