I have a class with a lot of member functions. Here are the ones giving me trouble (Segmentation Fault):
#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
}
I can call my error handling function runningError() from any member function except void update_timer_complete()
. When I do, I get a .exe crash.
There were a lot more member functions omitted.
If this helps, here is the class definition header file:
#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();
};
What could allow two equivalent member functions of the form private void doStuff()
to have unequal access to the same member function? One calls it fine, the other calls it and produces a segmentation fault!
If really required, here is the full code:
#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();
}