在qt程序中尝试通过引用传递对象时发生分段错误

问题描述 投票:0回答:1

我正在使用Qt并且已经使它在我的dialogs之前出现两个centralwidget。在我的第二个对话框(playerInfo)中,我创建了一个QcomboBox和一个QlineEdit,它包含一个int和一个QString。然后我将这些值存储到我的播放器类中。然而,当我创建我的centralwidget并尝试将玩家对象传递给它时,它会出现段错误。

我的main.cpp

int main( int argv, char* argc[] ) {
    int numberPlayers = 0;
  QApplication app( argv, argc );
  MainWindow mw;
  numPlayers pPlayers; //first dialog that prompts the user to enter in how many players
   numberPlayers = pPlayers.returnInput();
 playerInfo *pInfo = new playerInfo(numberPlayers, &mw); //user enters in each players info based off number of players
  pInfo->show();
  return app.exec();
}

playerInfo对话框:

#include "playerinfo.h"
using namespace std;

playerInfo::playerInfo( int players, MainWindow *mw, QWidget *parent) :
    QWidget(parent)
{
    max_players = players;
    wm = mw; //set wm to point to the address of the mainwindow object

    setFixedSize(400, 400);
    layout= new QVBoxLayout;
    this->setLayout(layout);

    title = new QLabel(tr("Please enter the following information:"));
    layout->addWidget(title);

    lineEdit = new QLineEdit; // create line edit
    layout->addWidget(lineEdit);

    comboBox = new QComboBox; // create combo box and add items to it
    QStringList items = QStringList() << "Hat" << "Car" << "Shoe" << "SpaceShip" << "Basketball" << "Ring";
    comboBox->addItems(items);
    layout->addWidget(comboBox);

    okay = new QPushButton(tr("Accept"));
    layout -> addWidget(okay);
    connect(okay, SIGNAL(clicked()), this, SLOT(storeInfo()));
}

QString playerInfo::getName() const
{
    return lineEdit->text();
}

int playerInfo::getIndex() const
{
    return comboBox->currentIndex();
}

void playerInfo::storeInfo()
{
    hide();
     index = getIndex();
    name = getName();
    wm->setPlayerData(index, name, pCounter);
    pCounter++;
    if (pCounter != max_players)
    {
         show();
    }
    else if (pCounter == max_players)
    {

        wm->setGUIWidgets(max_players);
        wm->createCentralWidget();
        wm->show();
    }

}

我的centralwidget.cpp:

#include "centralwidget.h"
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

CentralWidget::CentralWidget(Player *players[0], int input): QWidget() {

   for (int i = 0; i < input; i ++) 
   {
      p.append(players[i]); << still segfaulting
    // p[i] = players[i]; // segfaulting here <<<
   }
}

我想出了导致我的程序出现段错误的区域是当我尝试将从playerInfo Dialog传入的玩家的地址传递给CentralWidget类的私有变量时。 (p[i] = players[i];)。我错误地通过参考传递了吗?

如果您需要更多信息(如标题文件),请告诉我。谢谢你的帮助。

编辑::

#ifndef CENTRALWIDGET_H
#define CENTRALWIDGET_H
#include <QWidget>
#include <QtGui>
#include "player.h"

class CentralWidget: public QWidget {
  Q_OBJECT

  private:
   QVector<Player> *p;


  private slots:

 public:
    CentralWidget(Player *players[0], int input);

};

#endif

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui>
#include <iostream>
#include "guiplayervertical.h"
#include "centralwidget.h"

class MainWindow : public QMainWindow {
  Q_OBJECT

  private:
  Player *players[4];
  GUIPlayer* guiPlayers[4];
  QWidget *centralWidget;

  int input;
QList<int> index;
QList<QString> name;


  public:
    MainWindow();
    void setPlayerData(int _index, const QString &_name, int i);
    void setGUIWidgets(int input);
    void createCentralWidget();

};
#endif

mainwindow.cpp

#include "mainwindow.h"
using namespace std;
MainWindow::MainWindow() {
}


void MainWindow::setPlayerData(int _index, const QString &_name, int i)
{
    index.append(_index); // index is a member variable declared somewhere in your mainwindow.h
    name.append(_name); // name is a member variable declared somewhere in your mainwindow.h
    players[i] = new Player(name[i], index[i]);
    guiPlayers[i] = new GUIPlayerVertical( players[i]);
}


void MainWindow::setGUIWidgets(int input)
{
  if (input == 2)
  {
    addDockWidget( Qt::LeftDockWidgetArea, guiPlayers[0] );
    addDockWidget( Qt::RightDockWidgetArea, guiPlayers[1] );
  }
  else if (input == 3)
  {
    addDockWidget( Qt::LeftDockWidgetArea, guiPlayers[0] );
    addDockWidget( Qt::LeftDockWidgetArea, guiPlayers[1] );
    addDockWidget( Qt::RightDockWidgetArea, guiPlayers[2] );
  }
  else
  {
    addDockWidget( Qt::LeftDockWidgetArea, guiPlayers[0] );
    addDockWidget( Qt::LeftDockWidgetArea, guiPlayers[1] );
    addDockWidget( Qt::RightDockWidgetArea, guiPlayers[2] );
    addDockWidget( Qt::RightDockWidgetArea, guiPlayers[3] );
  }
}

void MainWindow::createCentralWidget()
{
    centralWidget = new CentralWidget(&players[0], input);

    setCentralWidget( centralWidget );
}
c++ qt segmentation-fault pass-by-reference
1个回答
0
投票

我没有真正挖出你遇到的问题,因为你的代码太连接了,但仍然遗漏了一些信息。例如,用户的输入未定义,因此如果玩家数量超过4,则会产生segfaulted。

但是,一些编码实践值得进行一些重构。由于你在p的分配方面遇到了问题,std::vector是从作为参数传递的数组的指针复制的,所以我建议你切换到一个更灵活,更不容易出错的方法。使用QVector或者在本例中使用private: QVector<Player*> players; ,您可以从可变大小的数组中受益,具有更好的内存管理,而不是重新创建自己的另一个容器,或依赖于固定大小的数组。

从你班级的成员开始,然后申报

players.append( new Player(name[i], index[i]) );

然后,使用填充容器

CentralWidget(const QVector<Player*>& players);

将vector作为参数传递给另一个类的构造函数时,使用相同类型的const引用,这相当于传递单个指针,而不是整个对象

centralWidget = new CentralWidget(players);

请注意,使用容器时,您不需要单独指定数组大小。最后,这简化了许多剩余的更改。您现在可以将整个成员作为参数传递

p = players;

并简单地使用它来复制它

for

不再需要qazxswpoi循环了。

© www.soinside.com 2019 - 2024. All rights reserved.