• 6675阅读
  • 7回复

[提问]为什么程序会报 double free or corruption? [复制链接]

上一主题 下一主题
离线caiwei_cs
 

只看楼主 倒序阅读 楼主  发表于: 2016-12-16
程序如下:
main:
  1. #include <QCoreApplication>
  2. #include "cc.h"
  3. int main(int argc, char *argv[])
  4. {
  5.     QCoreApplication a(argc, argv);
  6. //    cc *k = new cc;//不会报错
  7.     cc k;//会报错
  8.     return a.exec();
  9. }

cc.cpp

  1. #include "cc.h"
  2. #include <QTimer>
  3. #include <QDebug>
  4. cc::cc(QObject *parent) : QObject(parent)
  5. {
  6.     this->deleteLater();
  7.     qDebug()<<"deletelater called";
  8. }


cc.h

  1. #ifndef CC_H
  2. #define CC_H
  3. #include <QObject>
  4. class cc : public QObject
  5. {
  6.     Q_OBJECT
  7. public:
  8.     explicit cc(QObject *parent = 0);
  9. signals:
  10. public slots:
  11. };
  12. #endif // CC_H






运行程序会报错:deletelater called
*** Error in `/home/caiwei/tmp/11/build-dd-Qt_5_2_0_X86-Debug/dd': double free or corruption (out): 0x00007fff4779b910 ***
按 <RETURN> 来关闭窗口...

如果使用cc *k = new cc;就不会报错,或者不是在main函数里面使用就不会。
想不通为什么?

有人说,是main函数结束会析构一次,我自己deletelater一次,所以会有多重释放。但是我的理解是,return a.exec();是不会退出的。求助

离线flfw1314

只看该作者 1楼 发表于: 2016-12-16
return a.exec不会退出的话那就出大事了,他不退出怎么结束应用程序?其实在windows下,当程序收到quit消息时,主消息循环就会退出。就是你的a.exec就返回了。main返回之后的事就交给crt运行时库了,他要做的事其中之一就是对象的释放,就是你的cc对象k会释放,之后调用你的cc析构函数。之于你说的cc *k = new cc不会出错,而cc k会出错。这是c++里内存分布的原因。前者是在堆里面分配空间,需要自己释放;后者是在栈里面分配内存,有系统自己释放。so,new cc 你不显示调用delete 他是不会释放的,也就不会调用析构函数。而 cc k会在该变量的生存期结束之后自动释放。调用其析构函数。看着很简单的问题,其实涉及的细节很多。说了个大概。有问题再交流
走吧。。。。不管往哪里走
离线uidab

只看该作者 2楼 发表于: 2016-12-16
以前看得一个介绍内存泄露的文章,代码和你写的一样一样的。

附上链接
http://blog.csdn.net/taiyang1987912/article/details/29271549
有时候为了工作直接获得答案,而我却失去了思考的乐趣!


飘啊飘,何时能安居!
离线caiwei_cs

只看该作者 3楼 发表于: 2016-12-16
回 flfw1314 的帖子
flfw1314:return a.exec不会退出的话那就出大事了,他不退出怎么结束应用程序?其实在windows下,当程序收到quit消息时,主消息循环就会退出。就是你的a.exec就返回了。main返回之后的事就交给crt运行时库了,他要做的事其中之一就是对象的释放,就是你的cc对象k会释放,之后调用你的cc析构 .. (2016-12-16 12:39) 

我的意思是我不知道为什么这种情况 return a.exec()会退出。难道我销毁一个控件,消息循环就退出,结束程序,显然没有直接关系。
离线flfw1314

只看该作者 4楼 发表于: 2016-12-16
你程序退出的时候就是a.exec返回的时候,你这个报错是关闭程序的时候报的吧
走吧。。。。不管往哪里走
离线xzfn

只看该作者 5楼 发表于: 2016-12-17
等同于
int ret = a.exec();
return ret;

a.exec()虽然只有一句,里面确实整个消息循环所在。
单击x的时候,a.exec()会返回。
退出main时,deleteLater和out of scope都会调析构,两次。
离线caiwei_cs

只看该作者 6楼 发表于: 2016-12-19
回 uidab 的帖子
uidab:以前看得一个介绍内存泄露的文章,代码和你写的一样一样的。[表情]
附上链接
http://blog.csdn.net/taiyang1987912/article/details/29271549 (2016-12-16 15:34) 

谢谢!!!很好的解答了我的问题。
离线caiwei_cs

只看该作者 7楼 发表于: 2016-12-19
回 xzfn 的帖子
xzfn:
等同于
int ret = a.exec();
return ret;
a.exec()虽然只有一句,里面确实整个消息循环所在。
.......

我没有点击关闭程序。直接运行崩溃。

main改为:
  1. int main(int argc, char *argv[])
  2. {
  3.     QApplication a(argc, argv);
  4.     cc k;
  5.     qDebug()<<__LINE__;
  6.     int res = a.exec();
  7.     qDebug()<<__LINE__;
  8.     return res;
  9. }

错误提示:没有等到main退出,直接崩溃。所以这里虽然怀疑是两次析构,但是和main函数退出没有什么关系,貌似。当然我这里delete一个栈上的东西是不对的。

Starting /home/caiwei/QtTest/test2/build-test2-Qt_5_2_0_X86-Debug/test2...
deletelater called
19
*** Error in `/home/caiwei/QtTest/test2/build-test2-Qt_5_2_0_X86-Debug/test2': double free or corruption (out): 0x00007ffde6555d90 ***


快速回复
限100 字节
 
上一个 下一个