qt私有成员函数调用另一个成员函数使程序崩溃

qt private member function calling another member function crashes program

我有一个 class 有很多成员函数。以下是给我带来麻烦的问题(分段错误):

#include "mainwindow.h"
#include <QTimer>
#include <QDebug>
#include <QMessageBox>
#include "ui_mainwindow.h"
#include "LabJackUD.h"

MainWindow::MainWindow(QWidget *parent, LJ_HANDLE *lngHandle2) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    blah
}

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

void MainWindow::resetHandle() {
    //Open the first found LabJack U3.
    lngErrorcode = OpenLabJack(LJ_dtU3, LJ_ctUSB, "1", 1, lngHandle);
    runningErrors(lngErrorcode, __LINE__, 0);

    lngErrorcode = GoOne(*lngHandle);
    runningErrors(lngErrorcode, __LINE__, 0);
}

void MainWindow::runningErrors(LJ_ERROR lngErrorcode, long lngLineNumber, long lngIteration) {
    char err[255];

    if((lngErrorcode == 1015) && (!isOpen))
    {
        isOpen = true;

        //STOP EVERYTHING
        MainWindow::on_pushButton_clicked(false);
        //Create an error message dialog only to prompt to connect labjack.
        QMessageBox *msg = new QMessageBox();
        msg->show();
        msg->setText("WARNING:\n\nLabjack is not connected. Please\nconnect Labjack.");

    }

    if(lngErrorcode == 1003)
    {
        //attempt to solve handle problem by resetting handle
        OpenLabJack(LJ_dtU3, LJ_ctUSB, "1", 1, lngHandle);
        GoOne(*lngHandle);
    }

    if(lngErrorcode != LJE_NOERROR)
    {
        ui->textBrowser->show();
        ui->exitTextBrowser->show();

        ErrorToString(lngErrorcode,err);
        ui->textBrowser->setText(err);
    }
}


void MainWindow::update_timer_complete()
{

    //Display new LCD values
    //qDebug()<<"updateLCDs timeout";
    QString minutesTop = QString::number((cycleComplete->remainingTime()/1000)/7);
    QString secondsTop = QString::number((cycleComplete->remainingTime()/1000)%7);
    QString minutesBot = QString::number((nextExperiment->remainingTime()/1000)/7);
    QString secondsBot = QString::number((nextExperiment->remainingTime()/1000)%7);

    ui->lcdNumber->display(minutesTop+":"+secondsTop);
    ui->lcdNumber_2->display(minutesBot+":"+secondsBot);

    minutesTop.~QString();
    minutesBot.~QString();
    secondsTop.~QString();
    secondsBot.~QString();

    //I really wanted to check if stuff is working during each update.
    resetHandle(); //Will call runningError() handler if problem
}

我可以从任何成员函数 除了 void update_timer_complete() 调用我的错误处理函数 runningError()。当我这样做时,我遇到了 .exe 崩溃。

省略了很多成员函数。

如果这有帮助,这里是 class 定义头文件:

#include <QMainWindow>
#include "LabJackUD.h"
#include <QTimer>


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0, LJ_HANDLE* lngHandle = 0);
    ~MainWindow();

private slots:
    void cycle_timer_complete();

    void next_timer_complete(bool update = false);

    void update_timer_complete();

    void on_radioButton_pressed();

    void on_radioButton_2_pressed();

    void on_radioButton_released();

    void on_radioButton_3_pressed();

    void on_radioButton_4_pressed();

    void on_pushButton_toggled(bool checked);

    void on_pushButton_clicked();

    void on_pushButton_4_clicked();

    void on_pushButton_clicked(bool checked);

    void on_exitTextBrowser_clicked();

private:
    Ui::MainWindow *ui;
    LJ_HANDLE *lngHandle;
    LJ_ERROR lngErrorcode;
    void clearAll();
    void runningErrors(LJ_ERROR lngErrorcode, long lngLineNumber, long lngIteration);
    QTimer *cycleComplete;
    QTimer *nextExperiment;
    QTimer *updateLCDs;
    int selectedPin;
    int timer1;
    int timer2;
    int timer3;
    int prevTime, prevSpin1, prevSpin2, prevSpin3, prevSpin4;
    void resetHandle();
    void updatePins();
};

什么可以允许 private void doStuff() 形式的两个等效成员函数对同一个成员函数具有不平等的访问权限?一个调用它很好,另一个调用它并产生分段错误!

如果真的需要,这里是完整的代码:

    #include "mainwindow.h"
#include <QTimer>
#include <QDebug>
#include <QMessageBox>
#include "ui_mainwindow.h"
#include "LabJackUD.h"

bool isOpen = false;

MainWindow::MainWindow(QWidget *parent, LJ_HANDLE *lngHandle2) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    lngHandle = lngHandle2;
    cycleComplete = new QTimer(this);
    nextExperiment = new QTimer(this);
    updateLCDs = new QTimer(this);
    selectedPin = 0;
    timer1 = 0;
    timer2 = 0;
    timer3 = 0;
    lngErrorcode = 0;

    connect(cycleComplete,SIGNAL(timeout()),this,SLOT(cycle_timer_complete()));
    connect(nextExperiment,SIGNAL(timeout()),this,SLOT(next_timer_complete()));
    connect(updateLCDs,SIGNAL(timeout()),this,SLOT(update_timer_complete()));

    ui->textBrowser->hide();
    ui->textBrowser->raise();
    ui->exitTextBrowser->hide();
    ui->exitTextBrowser->raise();

    clearAll();
}

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

void MainWindow::resetHandle() {
    //Open the first found LabJack U3.
    lngErrorcode = OpenLabJack(LJ_dtU3, LJ_ctUSB, "1", 1, lngHandle);
    runningErrors(lngErrorcode, __LINE__, 0);

    lngErrorcode = GoOne(*lngHandle);
    runningErrors(lngErrorcode, __LINE__, 0);
}

void MainWindow::runningErrors(LJ_ERROR lngErrorcode, long lngLineNumber, long lngIteration) {
    char err[255];

    if((lngErrorcode == 1015) && (!isOpen))
    {
        isOpen = true;

        //STOP EVERYTHING
        MainWindow::on_pushButton_clicked(false);
        //Create an error message dialog only to prompt to connect labjack.
        QMessageBox *msg = new QMessageBox();
        msg->show();
        msg->setText("WARNING:\n\nLabjack is not connected. Please\nconnect Labjack.");

    }

    if(lngErrorcode == 1003)
    {
        //attempt to solve handle problem by resetting handle
        OpenLabJack(LJ_dtU3, LJ_ctUSB, "1", 1, lngHandle);
        GoOne(*lngHandle);
    }

    if(lngErrorcode != LJE_NOERROR)
    {
        ui->textBrowser->show();
        ui->exitTextBrowser->show();

        ErrorToString(lngErrorcode,err);
        ui->textBrowser->setText(err);

        //Qdebugging purposes
        qDebug() << ("Error number = ") << lngErrorcode;
        qDebug() << ("Error string = ") << err;
        qDebug() << ("Source line number = ") << lngLineNumber;
        qDebug() << ("Iteration = ") << lngIteration;

    }
}

void MainWindow::clearAll() {
    lngErrorcode = eDO(*lngHandle, 4, 0);
    runningErrors(lngErrorcode, __LINE__, 0);
    lngErrorcode = eDO(*lngHandle, 5, 0);
    runningErrors(lngErrorcode, __LINE__, 0);
    lngErrorcode = eDO(*lngHandle, 6, 0);
    runningErrors(lngErrorcode, __LINE__, 0);
    lngErrorcode = eDO(*lngHandle, 7, 0);
    runningErrors(lngErrorcode, __LINE__, 0);
    ui->radioButton->setChecked(false);
    ui->radioButton_2->setChecked(false);
    ui->radioButton_3->setChecked(false);
    ui->radioButton_4->setChecked(false);
}

void MainWindow::on_radioButton_pressed()
{
    clearAll();
    lngErrorcode = eDO(*lngHandle, 4, 1);
    runningErrors(lngErrorcode, __LINE__, 0);
    qDebug() << "radio button 1 pressed";
    ui->radioButton->setChecked(true);
}

void MainWindow::on_radioButton_2_pressed()
{
    clearAll();
    lngErrorcode = eDO(*lngHandle, 5, 1);
    runningErrors(lngErrorcode, __LINE__, 0);
    qDebug() << "radio button 2 pressed";
    ui->radioButton_2->setChecked(true);
}


void MainWindow::on_radioButton_3_pressed()
{
    clearAll();
    lngErrorcode = eDO(*lngHandle, 6, 1);
    runningErrors(lngErrorcode, __LINE__, 0);
    qDebug() << "radio button 3 pressed";
    ui->radioButton_3->setChecked(true);
}


void MainWindow::on_radioButton_4_pressed()
{
    clearAll();
    lngErrorcode = eDO(*lngHandle, 7, 1);
    runningErrors(lngErrorcode, __LINE__, 0);
    qDebug() << "radio button 4 pressed";
    ui->radioButton_4->setChecked(true);
}

void MainWindow::on_pushButton_toggled(bool checked)
{
}

void MainWindow::on_pushButton_clicked()
{

}

void MainWindow::cycle_timer_complete()
{
    qDebug()<<"cycleComplete timeout";
}

void MainWindow::next_timer_complete(bool update)
{
    qDebug()<<"nextExperiment timeout";
    if (!update) {
    selectedPin++;
    }

    qDebug()<<"selectedPin is " << selectedPin;

    switch ( selectedPin ) {
    case 4:
        qDebug() << "case 4";
        if (!update) {
        nextExperiment->start((ui->spinBox->value())*1000*7);
        }
        MainWindow::on_radioButton_pressed();
        break;
    case 5:
        qDebug() << "case 5";
        nextExperiment->start((ui->spinBox_2->value())*1000*7);
        MainWindow::on_radioButton_2_pressed();
        break;
    case 6:
        qDebug() << "case 6";
        nextExperiment->start((ui->spinBox_3->value())*1000*7);
        MainWindow::on_radioButton_3_pressed();
        break;
    case 7:
        qDebug() << "case 7";
        nextExperiment->start((ui->spinBox_4->value())*1000*7);
        MainWindow::on_radioButton_4_pressed();
        break;
    case 8:
        qDebug() << "case 8";
        MainWindow::on_pushButton_clicked(true);
        break;
    }


    //ui->pushButton->setText("Timer Complete");
}

void MainWindow::update_timer_complete()
{

    //Display new LCD values
    //qDebug()<<"updateLCDs timeout";
    QString minutesTop = QString::number((cycleComplete->remainingTime()/1000)/7);
    QString secondsTop = QString::number((cycleComplete->remainingTime()/1000)%7);
    QString minutesBot = QString::number((nextExperiment->remainingTime()/1000)/7);
    QString secondsBot = QString::number((nextExperiment->remainingTime()/1000)%7);

    ui->lcdNumber->display(minutesTop+":"+secondsTop);
    ui->lcdNumber_2->display(minutesBot+":"+secondsBot);

    minutesTop.~QString();
    minutesBot.~QString();
    secondsTop.~QString();
    secondsBot.~QString();

    //I really wanted to check if stuff is working during each update.
    resetHandle();
}

void MainWindow::on_pushButton_4_clicked()
{
    //figure out the total cycle time
    int t_total = ui->spinBox->value();
    t_total += ui->spinBox_2->value();
    t_total += ui->spinBox_3->value();
    t_total += ui->spinBox_4->value();

    //continue counting from previous state, correct for new values
    int newCycleTime = timer1;
    int newExpTime = timer2;
    int c1 = ui->spinBox->value();
    int c2 = ui->spinBox_2->value();
    int c3 = ui->spinBox_3->value();
    int c4 = ui->spinBox_4->value();
    switch(selectedPin) {
    case 4:
        newExpTime += (c1 - prevSpin1)*1000*7;
        newCycleTime += (c1+c2+c3+c4-prevSpin1-prevSpin2-prevSpin3-prevSpin4)*1000*7;
    case 5:
        newExpTime += (c2 - prevSpin2)*1000*7;
        newCycleTime += (c2+c3+c4-prevSpin2-prevSpin3-prevSpin4)*1000*7;
    case 6:
        newExpTime += (c3 - prevSpin3)*1000*7;
        newCycleTime += (c3+c4-prevSpin3-prevSpin4)*1000*7;
    case 7:
        newExpTime += (c4 - prevSpin4)*1000*7;
        newCycleTime += (c4-prevSpin4)*1000*7;
    }
    cycleComplete->start(newCycleTime);
    nextExperiment->start(newExpTime);
    updateLCDs->start(timer3);

    //change back appearance
    ui->pushButton_4->setEnabled(false);
    ui->pushButton->setText("STOP");
    ui->radioButton->setEnabled(false);
    ui->radioButton_2->setEnabled(false);
    ui->radioButton_3->setEnabled(false);
    ui->radioButton_4->setEnabled(false);
    ui->pushButton->setChecked(true);

    prevSpin1 = c1;
    prevSpin2 = c2;
    prevSpin3 = c3;
    prevSpin4 = c4;

    //no dialog open so reset
    isOpen=false;
}

void MainWindow::on_radioButton_released()
{
}

void MainWindow::on_pushButton_clicked(bool checked)
{
    if(checked) {
        //START NRML OPERATION
        //selectedPin will become 4 very shortly.
        selectedPin = 3;
        //figure out the total cycle time
        int t_total = ui->spinBox->value();
        t_total += ui->spinBox_2->value();
        t_total += ui->spinBox_3->value();
        t_total += ui->spinBox_4->value();
        t_total *= 1000*7;
        //keep track for continue option.
        prevTime = t_total;
        //configure timers
        cycleComplete->setInterval(t_total);
        nextExperiment->setInterval(0);
        updateLCDs->setInterval(100);

        ui->pushButton->setText("STOP");
        ui->radioButton->setEnabled(false);
        ui->radioButton_2->setEnabled(false);
        ui->radioButton_3->setEnabled(false);
        ui->radioButton_4->setEnabled(false);
        ui->pushButton_4->setEnabled(false);
        ui->spinBox->setEnabled(false);
        ui->spinBox_2->setEnabled(false);
        ui->spinBox_3->setEnabled(false);
        ui->spinBox_4->setEnabled(false);

        //start timers
        cycleComplete->start();
        nextExperiment->start();
        updateLCDs->start();

        //no dialog open so reset
        isOpen=false;
    } else {
        //STOP EVERYTHING REVERT EVERYTHING
        //enable continue button
        ui->pushButton_4->setEnabled(true);

        //revert appearance
        ui->pushButton->setText("START");
        ui->radioButton->setEnabled(true);
        ui->radioButton_2->setEnabled(true);
        ui->radioButton_3->setEnabled(true);
        ui->radioButton_4->setEnabled(true);
        ui->spinBox->setEnabled(true);
        ui->spinBox_2->setEnabled(true);
        ui->spinBox_3->setEnabled(true);
        ui->spinBox_4->setEnabled(true);

        //copy the current state for continuing
        //+1 because finished timer is -1
        timer1 = (cycleComplete->remainingTime()+1);
        timer2 = (nextExperiment->remainingTime()+1);
        timer3 = (updateLCDs->remainingTime()+1);
        prevSpin1 = ui->spinBox->value();
        prevSpin2 = ui->spinBox_2->value();
        prevSpin3 = ui->spinBox_3->value();
        prevSpin4 = ui->spinBox_4->value();

        //stop the timers
        cycleComplete->stop();
        nextExperiment->stop();
        updateLCDs->stop();
    }
}

void MainWindow::on_exitTextBrowser_clicked()
{
    ui->textBrowser->hide();
    ui->exitTextBrowser->hide();
}

奇怪的是,解决方案是重新排列成员函数定义的主体void update_timer_complete() {body}。我不得不把

    //I really wanted to check if stuff is working during each update.
resetHandle(); //Will call runningError() handler if problem

以上

    //Display new LCD values
//qDebug()<<"updateLCDs timeout";
QString minutesTop = QString::number((cycleComplete->remainingTime()/1000)/7);
QString secondsTop = QString::number((cycleComplete->remainingTime()/1000)%7);
QString minutesBot = QString::number((nextExperiment->remainingTime()/1000)/7);
QString secondsBot = QString::number((nextExperiment->remainingTime()/1000)%7);

ui->lcdNumber->display(minutesTop+":"+secondsTop);
ui->lcdNumber_2->display(minutesBot+":"+secondsBot);

minutesTop.~QString();
minutesBot.~QString();
secondsTop.~QString();
secondsBot.~QString();

出于某种原因,反过来会导致崩溃。我很想听听解释,如果有解释,我会 select 作为答案。