Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: Qt Creator странная ошибка пр изакрытии приложения  (Прочитано 1873 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн IfoR

  • Автор темы
  • Новичок
  • *
  • Сообщений: 16
    • Просмотр профиля
Здравствуйте! Я собственно в Qt новичок и вот возник вопрос.
Собственно пишу в Qt Creator новый виджет и как бы всё вроде работает нормально, но при закрытии приложения, т.е. так понимаю при удалении его из памяти, возникает эдакая плавающая ошибка:
*** glibc detected *** /home/ifor/blah/blah: free(): invalid next size (fast): 0x0000000001e896c0 ***
{далее список}
при чём она может и не возникнуть, например при удалении комментариев из кода деструктора виджета и последующий запуск проги под отладчиком ошибка перестала появляться даже после обычного запуска. Она так же напрямую зависит от объявлении в заголовке виджета переменных. Чем их больше, тем больше вероятность возникновения. Помогало от неё объявление указателей на переменные и создание самих переменных в конструкторе (и соответственное удаление их в деструкторе). Но опять же, чем больше указателей, тем больше вероятность. :) При отладки приложение прерывалось получая сообщение о закрытии от ОС на первой строчке деструктора виджета.
Была такая же ошибка и при создании виджета, но там я накосячил: объявил автоматический указатель на виджет в самом конструкторе формы и соответственно после выполнения конструктора указатель удалялся. Вопрос, где я ещё накосячил? :)
ОС: Ubuntu 10.04, Qt4

Заголовок виджета:
#ifndef CPUWIDGET_H
#define CPUWIDGET_H

#include <QWidget>
#include <QPainter>
#include <QColor>

class CPUWidget : public QWidget
{
Q_OBJECT
public:
    explicit CPUWidget(QWidget *parent = 0);
    ~CPUWidget();

protected:
    void paintEvent(QPaintEvent *);
    void resizeEvent(QResizeEvent *);

private:
    QColor ColorBackground,ColorSelected,ColorBox,ColorLines,ColorText; //Нужные переменные
    float qAssemblyRegisters,qMemoryKesh,qAssemblyMemory;
    unsigned int XAssemblyRegisters,XMemoryKesh,YAssemblyMemory;

};

#endif // CPUWIDGET_H

Реализация виджета:
#include "cpuwidget.h"

CPUWidget::CPUWidget(QWidget *parent) :
    QWidget(parent)
{
    ColorBackground.setRgb(0,0,0,255); //Присваиваем стандартные величины
    ColorSelected.setRgb(255,255,255,100);
    ColorBox.setRgb(255,255,255,255);
    ColorLines.setRgb(150,150,150,255);
    ColorText.setRgb(200,200,200,255);

    qAssemblyRegisters=0.6;
    qMemoryKesh=0.6;
    qAssemblyMemory=0.6;

}

CPUWidget::~CPUWidget()
{

}

void CPUWidget::resizeEvent(QResizeEvent *)
{
    XAssemblyRegisters=(this->width()-1)*qAssemblyRegisters; //Модифицируем места положения линий на виджете
    XMemoryKesh=(this->width()-1)*qMemoryKesh;
    YAssemblyMemory=(this->height()-1)*qAssemblyMemory;
}

void CPUWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this); //Перирисовываем виджет

    painter.setPen(ColorBox.toRgb());
    painter.setBrush(ColorBackground.toRgb());
    painter.drawRect(0,0,this->width()-1,this->height()-1); //Рамка

    painter.setPen(ColorLines.toRgb());
    painter.drawLine(XAssemblyRegisters,1,XAssemblyRegisters,YAssemblyMemory);
}

Заголовок формы:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "cpuwidget.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    CPUWidget* CPU; //Указатель на виджет

protected:
    void changeEvent(QEvent *e);

private:
    Ui::MainWindow *ui;

};

#endif // MAINWINDOW_H

Реализация формы:
#include "mainwindow.h"
#include "ui_mainwindow.h"



MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    CPU = new CPUWidget(this); //Создание виджета
    ui->verticalLayout_2->addWidget(CPU); //Добавление виджета в компоновщик на форме
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }

}

Прям сейчас пока код работает без сбоев (после запуска под отладчиком), но боюсь что если добавить ещё несколько переменных то это появится опять.
P.S. Раньше у меня бывало что программа и вообще сразу получало сообщение о закрытие при запуске, но я уже не помню где.
P.P.S. Тему рядом видел и посмотреть под отладчиком попробую, но меня удивляет что такой простой код вызывает ошибку. Наверняка ошибка в моём коде...
P.P.P.S. Убрал ручное определение виджета и расположил его в Дизайнере и вроде всё даже работает, но всё же интересно, что это могло быть?
« Последнее редактирование: 08 Июля 2010, 21:44:55 от IfoR »

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
Цитировать
Прям сейчас пока код работает без сбоев (после запуска под отладчиком), но боюсь что если добавить ещё несколько переменных то это появится опять.
Тоесть ты привёл рабочий код и просишь помочь с поиском ошибки в нём? :) Интересный подход. Давай уж не работающий код выложи. В этом я ошибок не вижу, хотя я сейчас на работе и детально его построчно не разбирал, только мельком пробежался глазами.
« Последнее редактирование: 09 Июля 2010, 19:53:47 от VestniK »

Оффлайн IfoR

  • Автор темы
  • Новичок
  • *
  • Сообщений: 16
    • Просмотр профиля
Дык прикол в том, что тот же самый код сначала вызывал ошибку, но стоило запустить такое шаманское действие, как запустить отладчик, как проблема сама собой исчезла.

Вот провёл эксперимент:
Добавил в заголовочный файл виджета в графу private: QColor C1,C2,C3,C4,C5;:
(Тут у меня код немного дописан, но он ещё работает. Кроме того что написано ниже больше ничего не менялось.)
class CPUWidget : public QWidget
{
...
private:
    enum {LineAssemblyRegisters,LineMemoryKesh,LineAssemblyMemory};
    QColor ColorBackground,ColorSelected,ColorBox,ColorLines,ColorText;
    float qAssemblyRegisters,qMemoryKesh,qAssemblyMemory;
    int XAssemblyRegisters,XMemoryKesh,YAssemblyMemory;
    int mouseMoveElement;

    QColor C1,C2,C3,C4,C5;
};

Программа сразу же перестала запускаться.
В конструкторе виджета так же их определил, но проблема не исчезла.
Отладчик говорит Segmentation fault.
Трейсер останавливается на строке:

void setupUi(QMainWindow *MainWindow)
    {
        if (MainWindow->objectName().isEmpty())
            MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
        MainWindow->resize(600, 400);
        centralWidget = new QWidget(MainWindow);
        centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
        verticalLayout = new QVBoxLayout(centralWidget);
        verticalLayout->setSpacing(6);
        verticalLayout->setContentsMargins(11, 11, 11, 11);
        verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
        CPU = new CPUWidget(centralWidget);
        CPU->setObjectName(QString::fromUtf8("CPU")); //<-- Тут

        verticalLayout->addWidget(CPU);

        MainWindow->setCentralWidget(centralWidget);
        menuBar = new QMenuBar(MainWindow);
...
}

Тоже самое происходит, если определить переменные как int.
Стоит это убрать, как всё опять начинает работать.
Вот я и не могу определить где у меня косяк.

P.S. Код реализации немного вырос, но если надо, то выложу.

Пользователь решил продолжить мысль 10 Июля 2010, 11:44:13:
Хе, кажется я понял в чём была проблема.
При создании проекта я на будущее включил поддержку OpenGL и даже создал небольшой класс на QGLWidget, но нигде его не подключал. Однако никакой гарантии, что он был написан верно нет. Попробовал снять поддержку OpenGL и убрать этот класс - заработало. Также попробовал включить OpenGL, но без класса - продолжает работать. :)
Даже и не подумал, что просто слева стоящий класс который включён в проект, но нигде не используется может так повлиять. :)
« Последнее редактирование: 10 Июля 2010, 11:44:13 от IfoR »

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
В принципе при определённом стечении обсьоятельств может. Но чтобы понять что и как уже весь код разбирать нужно.

 

Страница сгенерирована за 0.054 секунд. Запросов: 25.