简体   繁体   中英

Why does this code segfault on the w.show() call?

Subject says it all, here is the code:

I am using windows 7 64-bit with qt-opensource-windows-x86-mingw482_opengl-5.3.1

I posted the effected code below. When debugging the crash, I get a segfault on the w.show() line in the main.cpp file

EDIT: Sorry forget to add that it does not crash if I comment out the line:

//mainLayout->addLayout(oldLayout,0,0,1,1,Qt::AlignLeft);

it then corectly shows the mainwindow with the widget, but when I try to add a layout to the layout, it crashes...

main.cpp:

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.cpp

#include <QLabel>
#include <QString>

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setupWidgets();    
}


void MainWindow::setupWidgets() {

    mainWidget = new QWidget;
    mainLayout = new QGridLayout;

    setupOld();    

    setCentralWidget(mainWidget);
    mainWidget->setLayout(mainLayout);
    mainLayout->addLayout(oldLayout,0,0,1,1,Qt::AlignLeft);
}

void MainWindow::setupOld() {
    oldLayout = new QGridLayout;

    oldX = new QDoubleSpinBox;
    oldX->setRange(minNum,maxNum);
    oldX->setDecimals(precision);
    oldX->setSuffix(suffix);

    oldY = new QDoubleSpinBox;
    oldY->setRange(minNum,maxNum);
    oldY->setDecimals(precision);
    oldY->setSuffix(suffix);

    oldZ = new QDoubleSpinBox;
    oldZ->setRange(minNum,maxNum);
    oldZ->setDecimals(precision);
    oldZ->setSuffix(suffix);

    QLabel lblX, lblY, lblZ;
    lblX.setText("Old X Coord: ");
    lblY.setText("Old Y Coord: ");
    lblZ.setText("Old Z Coord: ");

    oldLayout->addWidget(&lblX,0,0,1,1,Qt::AlignLeft);
    oldLayout->addWidget(oldX,0,1,1,1,Qt::AlignLeft);
    oldLayout->addWidget(&lblY,1,0,1,1,Qt::AlignLeft);
    oldLayout->addWidget(oldY,1,1,1,1,Qt::AlignLeft);
    oldLayout->addWidget(&lblZ,2,0,1,1,Qt::AlignLeft);
    oldLayout->addWidget(oldZ,2,1,1,1,Qt::AlignLeft);
}

I think the reason is in the following code:

QLabel lblX, lblY, lblZ;
[..]
oldLayout->addWidget(&lblX,0,0,1,1,Qt::AlignLeft);

You create label objects in the stack and use them in your layout. Labels are deleting after the execution exists the MainWindow::setupOld() function, so your layout contains references to the deleted objects.

To fix the problem you need to create your labels allocating memory from the heap as you do for QDoubleSpinBox es:

QLabel *lblX = new QLabel("Old X Coord: ");
[..]
oldLayout->addWidget(lblX,0,0,1,1,Qt::AlignLeft);

The below works. Note how I've factored out repetitive code, put all the objects as direct members of MainWindow , and leveraged the initializer list in the constructor.

You don't have to use QMainWindow if you don't wish to use its other features (docking areas, status bar, etc.). In the code below, you could easily replace QMainWindow with QWidget , with following other changes:

  1. Set the layout on this instead of m_central ,

  2. Remove the setCentralWidget call.

#include <QApplication>
#include <QMainWindow>
#include <QLabel>
#include <QGridLayout>
#include <QDoubleSpinBox>

class MainWindow : public QMainWindow {
   QWidget m_central;
   QGridLayout m_centralLayout;
   QDoubleSpinBox m_oldX, m_oldY, m_oldZ;
   QLabel m_lblX, m_lblY, m_lblZ;
public:
   MainWindow(QWidget * parent = 0, Qt::WindowFlags flags = 0);
};

MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags) :
   QMainWindow(parent, flags),
   m_centralLayout(&m_central),
   m_lblX("Old X Coord: "),
   m_lblY("Old Y Coord: "),
   m_lblZ("Old Z Coord: ")
{
   QList<QDoubleSpinBox*> spins;
   spins << &m_oldX << &m_oldY << &m_oldZ;
   int i = 0;
   foreach (QDoubleSpinBox * spin, spins) {
      spin->setRange(0.0, 1.0);
      spin->setDecimals(3);
      spin->setSuffix(" km");
      m_centralLayout.addWidget(spin, i++, 1);
   }

   m_centralLayout.addWidget(&m_lblX, 0, 0);
   m_centralLayout.addWidget(&m_lblY, 1, 0);
   m_centralLayout.addWidget(&m_lblZ, 2, 0);

   setCentralWidget(&m_central);
}

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   MainWindow w;
   w.show();
   return a.exec();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM