查看完整版本: [-- 为什么程序会报 double free or corruption? --]

QTCN开发网 -> Qt基础编程 -> 为什么程序会报 double free or corruption? [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

caiwei_cs 2016-12-16 10:56

为什么程序会报 double free or corruption?

程序如下:
main:
  1. #include <QCoreApplication>
    #include "cc.h"

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);

    //    cc *k = new cc;//不会报错

        cc k;//会报错

        return a.exec();
    }

cc.cpp

  1. #include "cc.h"
    #include <QTimer>
    #include <QDebug>

    cc::cc(QObject *parent) : QObject(parent)
    {
        this->deleteLater();
        qDebug()<<"deletelater called";
    }


cc.h

  1. #ifndef CC_H
    #define CC_H

    #include <QObject>

    class cc : public QObject
    {
        Q_OBJECT
    public:
        explicit cc(QObject *parent = 0);

    signals:

    public slots:
    };

    #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 2016-12-16 12:39
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 2016-12-16 15:34
以前看得一个介绍内存泄露的文章,代码和你写的一样一样的。

附上链接
http://blog.csdn.net/taiyang1987912/article/details/29271549

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

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

flfw1314 2016-12-16 16:36
你程序退出的时候就是a.exec返回的时候,你这个报错是关闭程序的时候报的吧

xzfn 2016-12-17 15:25
等同于
int ret = a.exec();
return ret;

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

caiwei_cs 2016-12-19 10:23
uidab:以前看得一个介绍内存泄露的文章,代码和你写的一样一样的。[表情]
附上链接
http://blog.csdn.net/taiyang1987912/article/details/29271549 (2016-12-16 15:34) 

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

caiwei_cs 2016-12-19 10:33
xzfn:
等同于
int ret = a.exec();
return ret;
a.exec()虽然只有一句,里面确实整个消息循环所在。
.......

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

main改为:
  1. int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);

        cc k;

        qDebug()<<__LINE__;

        int res = a.exec();

        qDebug()<<__LINE__;

        return res;
    }

错误提示:没有等到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 ***




查看完整版本: [-- 为什么程序会报 double free or corruption? --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled