PDA

View Full Version : Segmentation fault when closing window by slot



mupilz
31st May 2010, 18:24
hi,
I need some help with a program, I'm writing.
I added some widgets on a QGraphicsScene, one of those is a menu. This menu got a button to close the program. When I click this button, the program exists - yes, exactly, what it should do, but it does because of a segmentation fault. This only happens on my PC (amd64 Ubuntu 10.04), on my notebook all works fine (i686 Sidux 2009-04). Both are running Qt 4.6.2.

Here the code of the menu class:



//mainmenu.h

#ifndef MAINMENU_H
#define MAINMENU_H

#include <QWidget>
#include <QPushButton>
#include <QBoxLayout>

class mainMenu : public QWidget
{
Q_OBJECT
public:
mainMenu(QWidget *mainWindow = 0);
~mainMenu();

private:
QWidget *main;
QHBoxLayout *hLayout;
QPushButton *settings;
QPushButton *quit;

signals:

public slots:

};

#endif // MAINMENU_H




// mainmenu.cpp
#include "../headers/mainmenu.h"

mainMenu::mainMenu(QWidget *mainWindow)
{
main = mainWindow;

this->setStyleSheet(tr("background:rgba(255, 255, 255, 50);"));
this->hide();
hLayout = new QHBoxLayout(this);

settings = new QPushButton(tr("Settings"));
quit = new QPushButton(tr("Quit"));

hLayout->addWidget(settings);
hLayout->addWidget(quit);

connect(quit, SIGNAL(clicked()), main, SLOT(close()));
}

mainMenu::~mainMenu()
{
delete hLayout;
delete settings;
delete quit;
delete main;
}


if some info is missing, I'll post it :)

mfg mupilz

EDIT: that is the output in the console:

X Error: BadColor (invalid Colormap parameter) 12
Major opcode: 1 (X_CreateWindow)
Resource id: 0x3e00006
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
Extension: 152 (RENDER)
Minor opcode: 4 (RenderCreatePicture)
Resource id: 0x3e0005b
X Error: BadWindow (invalid Window parameter) 3
Major opcode: 2 (X_ChangeWindowAttributes)
Resource id: 0x3e0005b
X Error: BadWindow (invalid Window parameter) 3
Major opcode: 2 (X_ChangeWindowAttributes)
Resource id: 0x3e0005b
X Error: BadWindow (invalid Window parameter) 3
Major opcode: 2 (X_ChangeWindowAttributes)
Resource id: 0x3e0005b
X Error: BadWindow (invalid Window parameter) 3
Major opcode: 8 (X_MapWindow)
Resource id: 0x3e0005b
X Error: BadWindow (invalid Window parameter) 3
Major opcode: 2 (X_ChangeWindowAttributes)
Resource id: 0x3e0005b
X Error: GLXBadDrawable 146
Extension: 136 (Uknown extension)
Minor opcode: 5 (Unknown request)
Resource id: 0x3e0005b
QGLContext::makeCurrent(): Failed.
The program has unexpectedly finished.

Zlatomir
31st May 2010, 18:39
Look for one of the following possible causes of Segmentation fault:
# buffer overflow
# using uninitialized pointers
# dereference NULL pointers
# attempt to access memory the program does not own.
# attempt to alter memory the program does not own

And one more thing, this destructor: (CAREFUL THIS DEPENDS OF YOUR ACTUAL CODE, double check and delete only what doesn't has a parent)


mainMenu::~mainMenu()
{
delete hLayout; // the layout shouldn't be deleted in any case
delete settings; // this two only if they have no parent
delete quit; //
delete main; // and most likely you need to delete only this
// because the rest looks like they have "main" as a parent and will be automatically deleted
}

mupilz
31st May 2010, 19:41
hm, I don't really know, which of the possibilities could be it :(.
Here is the output of the debugger, but I don't understand it :confused:
click (http://img28.imageshack.us/img28/14/screenshotad.png)
how should I understand it, or could someone say me, what that should tell me?

Zlatomir
31st May 2010, 19:55
Did you check that destructor? because that might be the problem ( i don't know about the others, but the Layout has a parent for sure //everything has a parent i took a better look at your code ;) )

LE:
try the destructor like this:


mainMenu::~mainMenu()
{
//delete hLayout; // the layout shouldn't be deleted in any case
//delete settings; // this two only if they have no parent
//delete quit; //
delete main; // and most likely you need to delete only this
// because the rest looks like they have "main" as a parent and will be automatically deleted
}

I'm pretty sure this will fix your problem ;)

mupilz
31st May 2010, 20:03
yes, I did, I removed it completely, same result.

EDIT: tested your version, changed nothing

Zlatomir
31st May 2010, 20:16
Then the problem lies in a different place, take a look in the other classes destructors for similar problems.

mupilz
31st May 2010, 20:42
I looked for that, checked every destructor, changed nothing,
but when I don't add the menu as widget to the graphicsView, it won't give me a seg fault.

Zlatomir
31st May 2010, 21:28
Please post the code that is using that menu, because you are passing a window(widget) to your class constructor and you delete it on close(on destructor). And you tell that default is 0, but assume that a pointer to window/widget is passed.
And you allocate with new in main.cpp and delete another pointer that points to that dynamic memory.

Please also try to explain a little bit the logic flow of your application, maybe we can give you a better/easier solution to achieve same result without passing resources from one place to another and not know exactly where to delete them.

Anyway, first post content of main.cpp.

mupilz
1st June 2010, 07:30
main.cpp -> uses GraphicsView as main widget -> uses GL as viewport -> adds some widgets

//main.cpp
#include <iostream>
#include <QtGui/QApplication>
#include "headers/net.h"
#include "headers/player.h"
#include "headers/config.h"
#include "headers/consts.h"
#include "headers/graphicsview.h"
#include "headers/py.h"
using namespace std;


int main(int argc, char **argv)
{
QApplication a(argc, argv);
Config config;
GraphicsView *view = new GraphicsView(config.read());
view->setWindowIcon(*new QIcon("images/logo.png"));
view->setWindowTitle(QApplication::tr("Ryna Online"));
view->show();
return a.exec();
}

// graphicsview.cpp, this is the main widget of the window
#include "../headers/graphicsview.h"

GraphicsView::GraphicsView(configuration config)
{
conf = config;
setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
setViewportUpdateMode(QGraphicsView::FullViewportU pdate);
gl = new GL(conf, this);
setScene(gl);
if (conf.fullscreen == 1)
{
this->showFullScreen();
}
else
{
QDesktopWidget desktop;
int
x = (desktop.availableGeometry(desktop.screenNumber(th is)).width() / 2) - (conf.resX / 2),
y = (desktop.availableGeometry(desktop.screenNumber(th is)).height() / 2) - (conf.resY / 2);
this->move(x, y);
}
this->setFixedSize(conf.resX, conf.resY);
}

GraphicsView::~GraphicsView()
{
}

void GraphicsView::resizeEvent(QResizeEvent *e)
{
if (scene())
{
scene()->setSceneRect(QRect(QPoint(0, 0), e->size()));
}
QGraphicsView::resizeEvent(e);
}

void GraphicsView::resize(int w, int h)
{
this->setFixedSize(w, h);
}

// graphicsview.h
#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H

// some includes


class GraphicsView : public QGraphicsView
{
public:
GraphicsView(configuration config);
~GraphicsView();
void resize(int w, int h);

private:
configuration conf;
GL *gl;

protected:
void resizeEvent(QResizeEvent *e);
};

#endif // GRAPHICSVIEW_H

// gl.cpp GraphicsView calls this widget as viewport
#include "../headers/gl.h"

GL::GL(configuration config, QWidget *parent)
{
conf = config;
par = parent;

// +++ menu widget
menu = new mainMenu(par); // and here the menu is added as widget to the gl widget, with a pointer to GraphicsView
addWidget(menu); // if I comment this row out, all works without seg fault, but I want the menu as widget on the graphicsview
menu->move(conf.resX/2-menu->width()/2, 10);
// --- menu widget

// +++ char info widget
info = new charInfo();
addWidget(info);
// --- char info widget

// +++ console widget
console = new Console(par);
console->setFixedSize(conf.resX, conf.resY/2);
addWidget(console);
// --- console widget
status = true;
}

GL::~GL()
{
}

void GL::drawBackground(QPainter *painter, const QRectF &)
{
// drawing the background
}

void GL::keyPressEvent(QKeyEvent *e)
{
// set keys for showing the menu, and some other things
}

// gl.h
#ifndef GL_H
#define GL_H

// some includes and stuff


class GL : public QGraphicsScene
{
Q_OBJECT
public:
GL(configuration config, QWidget *parent);
~GL();

protected:
void drawBackground(QPainter *painter, const QRectF &);
void keyPressEvent(QKeyEvent *e);

private:
int mouseX;
int mouseY;
int mouseButton;
int width;
int height;
int depth;
bool status;
configuration conf;
charInfo *info;
Console *console;
mainMenu *menu;
QWidget *par;
};

#endif // GL_H

Zlatomir
1st June 2010, 15:27
That menu with two buttons, why didn't you make it member of main window? Or you can make it a QMenu.

Because you are doing some "not recommended" stuff right now, by that i mean:
1) the passing of QWidget pointer in the constructor (pointer dynamically allocated elsewhere) and delete it in the destructor (in your case you should't delete it in destructor)
1.1) The MainWindow is recommended to be allocated on stack in the main function (so that will be parent of everything else and trigger the deletion of it's children, or if you allocate the mainWindow dynamically, you need to do something like this:


//...
MainWindow *w = new MainWindow(0);

w->show();

int ret = app.exec();

delete w;
return ret;
}


2) You have a class (mainMenu) that inherit QWidget and has a QWidget member, this is another thing i don't recommend. So choose if your class "is a" QWidget or needs to "have a" QWidget as member...

Right now i can't tell you where you mess-up with dynamically allocated memory and cause that Segmentation fault, there are too many places where you might do it, you need to practice with debugger to solve this...

or the better solution is to redesign your application so that you don't create yourself that "traps" where you can "lose" memory and/or access random memory

mupilz
4th June 2010, 16:33
thank you for your help ;) I used a QMenu for the menu, and now all works fine without seg fault.