指针无效 - 内存 - Qt

时间:2013-07-19 10:29:18

标签: c++ qt memory gdb valgrind

我想告诉你一个奇怪的问题,我的Qt应用程序。

我有两个窗口:第一个是QMainWindow,第二个是QDialog派生类。 QMainWindow显示QDialog one,它有一个表单和一个QPushButton,以便使用QFileDialog :: getOpenFileName。

当我第一次运行我的应用程序时(系统启动后)我遇到内存问题:

*** Error in `/home/nico/Documents/Projets_QtCreator/build-utilitaireTwsGraph-Kit_test-Debug/utilitaireTwsGraph': free(): invalid pointer: 0x000000000090cd40 ***

要重现此问题,我必须重新启动系统,因此我认为这是一个典型的损坏内存错误。我做了一些调查:

首先,我尝试使用gdb找到有罪的行。它告诉我:

Program received signal SIGABRT, Aborted.
0x00007ffff63ac037 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56  ../nptl/sysdeps/unix/sysv/linux/raise.c: Aucun fichier ou dossier de ce type.

堆栈跟踪显示:

(gdb) where
#0  0x00007ffff63ac037 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff63af698 in __GI_abort () at abort.c:90
#2  0x00007ffff63e95ab in __libc_message (do_abort=do_abort@entry=2, fmt=fmt@entry=0x7ffff64fc860 "*** Error in `%s': %s: 0x%s ***\n")
    at ../sysdeps/unix/sysv/linux/libc_fatal.c:199
#3  0x00007ffff63f5a46 in malloc_printerr (ptr=0x90cd40, str=0x7ffff64f8825 "free(): invalid pointer", action=3) at malloc.c:4902
#4  _int_free (av=<optimized out>, p=0x90cd30, have_lock=0) at malloc.c:3758
#5  0x00007fffeea21d76 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#6  0x00007ffff50f6538 in g_object_unref () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#7  0x00007fffeea0f21b in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#8  0x00007fffeea13584 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#9  0x00007ffff50f6538 in g_object_unref () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#10 0x00007fffee9b59ea in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#11 0x00007fffee9eaf5f in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#12 0x00007ffff50f155e in g_closure_invoke () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#13 0x00007ffff51030e4 in ?? () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#14 0x00007ffff510ad11 in g_signal_emit_valist () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#15 0x00007ffff510af92 in g_signal_emit () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#16 0x00007fffeea8f580 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#17 0x00007ffff50f7640 in g_object_run_dispose () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#18 0x00007fffee9b59ea in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#19 0x00007fffee9eaf5f in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#20 0x00007ffff50f155e in g_closure_invoke () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#21 0x00007ffff51030e4 in ?? () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#22 0x00007ffff510ad11 in g_signal_emit_valist () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#23 0x00007ffff510af92 in g_signal_emit () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#24 0x00007fffeea8f580 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#25 0x00007ffff50f7640 in g_object_run_dispose () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#26 0x00007fffee9eaf5f in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#27 0x00007ffff50f1620 in g_closure_invoke () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#28 0x00007ffff51030e4 in ?? () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#29 0x00007ffff510ad11 in g_signal_emit_valist () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#30 0x00007ffff510af92 in g_signal_emit () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#31 0x00007fffeea8f580 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#32 0x00007ffff50f7640 in g_object_run_dispose () from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#33 0x00007ffff7684879 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#34 0x00007ffff77c537a in QFileDialog::getOpenFileName(QWidget*, QString const&, QString const&, QString const&, QString*, QFlags<QFileDialog::Option>) ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#35 0x0000000000409277 in FenetreSelectionStatusMonitor::selectionnerStatusMonitor (this=0x825710)
    at ../utilitaireTwsGraph/dev/src/vue/fenetreSelectionStatusMonitor.cpp:89

所以我猜这个问题出在我的getOpenFileName调用中。

然后,我删除了我的QDialog的模态属性(没有效果),我使用了valgrind,但它没有帮助我:

 Invalid free() / delete / delete[] / realloc()
==2237==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2237==    by 0xE194D75: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.17)
==2237==    by 0x78F3537: g_object_unref (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==    by 0xE18221A: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.17)
==2237==    by 0xE186583: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.17)
==2237==    by 0x78F3537: g_object_unref (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==    by 0xE1289E9: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.17)
==2237==    by 0xE15DF5E: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.17)
==2237==    by 0x78EE55D: g_closure_invoke (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==    by 0x79000E3: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==    by 0x7907D10: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==    by 0x7907F91: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==  Address 0x155066d0 is 720 bytes inside a block of size 1,008 alloc'd
==2237==    at 0x4C2A896: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2237==    by 0x4C2A987: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2237==    by 0x6F22A07: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3600.0)
==2237==    by 0x6F6C3EB: g_slice_alloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3600.0)
==2237==    by 0x6F6C445: g_slice_alloc0 (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3600.0)
==2237==    by 0x790E8C4: g_type_create_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==    by 0x78F9A4B: g_param_spec_internal (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==    by 0x78FDA11: g_param_spec_object (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==    by 0xD98D4CB: ??? (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.3600.0)
==2237==    by 0x790C955: g_type_class_ref (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==    by 0x78F535C: g_object_new_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==    by 0x78F5803: g_object_new (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3600.0)
==2237==

当我不使用原生对话框时,我没有这个问题。所以我认为它可能是一个系统依赖或包错误,但我有一个其他应用程序使用GetOpenFileName(完全相同的调用),我可以编译它,它的工作原理。

GetOpenFileName调用位于Qt Slot中:

void FenetreSelectionStatusMonitor::selectionnerStatusMonitor() {
    QFileDialog::getOpenFileName(this, tr("Fichier descriptif du status monitor"), "/home",tr("Lst (*.lst)"));
}

头文件(我删除了无用的声明):

#ifndef FENETRE_SELECTION_STATUS_MONITOR
#define FENETRE_SELECTION_STATUS_MONITOR

#include <QFileDialog>

class FenetreSelectionStatusMonitor : public QDialog {
    Q_OBJECT
    public:
        FenetreSelectionStatusMonitor(int hauteur, int largeur, QWidget* parent);

    private slots:
        void selectionnerStatusMonitor();
};

#endif // FENETRE_SELECTION_STATUS_MONITOR

我想我会尝试重新安装我的qt包,因为我现在没有任何想法。我检查了调用参数,但没有找到任何东西。因为我的课程缺乏稳定性,我问我问题。即使我没有遇到任何问题,我也不知道如何证明我的程序不会崩溃并且没有内存泄漏(带库的valgrind很难使用),这非常令人厌恶!

非常感谢您阅读这篇文章,我希望您能帮助我:)。

编辑:我买了一个新项目,只需要一个简单的QMainWindow调用一个调用GetOpenFileName的QDialog。我有完全相同的问题。

这个新项目有两个类和一个主要的:

main.cpp中:

#include <QApplication>
#include "mainWindowTest.h"

int main(int argc, char** argv) {
    QApplication app(argc,argv);
    MainWindowTest window;
    window.show();

    return app.exec();
}

mainWindowTest.h:

#ifndef MAIN_WINDOW_TEST_H
#define MAIN_WINDOW_TEST_H

#include <QMainWindow>
#include <QWidget>
#include <QHBoxLayout>
#include <QPushButton>
#include "dialogTest.h"

class MainWindowTest : public QMainWindow {
    Q_OBJECT

    public:
        MainWindowTest();

    private slots:
        void openDialog();
};

#endif //MAIN_WINDOW_TEST_H    

dialogTest.h:

#ifndef DIALOG_TEST_H
#define DIALOG_TEST_H

#include <QDialog>
#include <QWidget>
#include <QHBoxLayout>
#include <QPushButton>
#include <QFileDialog>

class DialogTest : public QDialog {
    Q_OBJECT

    public:
        DialogTest();

    private slots:
        void openFile();
};

#endif //DIALOG_TEST_H

mainWindowTest.cpp

#include "mainWindowTest.h"

MainWindowTest::MainWindowTest() {
    setMinimumSize(200,200);

    QWidget* widget = new QWidget();
    QHBoxLayout* layout = new QHBoxLayout();
    QPushButton* btnOpen = new QPushButton("Open dialog");
    connect(btnOpen, SIGNAL(clicked()), this, SLOT(openDialog()));
    layout->addWidget(btnOpen);

    widget->setLayout(layout);
    setCentralWidget(widget);
}

void MainWindowTest::openDialog() {
    DialogTest dialog;
    dialog.exec();
}

dialogTest.cpp

#include "dialogTest.h"

DialogTest::DialogTest() {
    QHBoxLayout* layout = new QHBoxLayout();
    QPushButton* btnOpen = new QPushButton("Open file");
    connect(btnOpen, SIGNAL(clicked()), this, SLOT(openFile()));
    layout->addWidget(btnOpen);

    setLayout(layout);
}

void DialogTest::openFile() {
    QFileDialog::getOpenFileName(this, tr("Fichier descriptif du status monitor"), "/home", tr("Lst (*.lst)"));
}

0 个答案:

没有答案