Objects on Stack in class header files



  • Hey there bit of a noob question but trying to understand why this doesn't work, currently have a simple timer class that wraps around QTimer. Then i have another class that creates an object pointer of Timer however when i run the program it just crashes. If i just create an object inside the class that isn't a pointer the code works fine, can anyone explain to me whats happening in the background, thanks (also works when placing the object on the Heap instead of the stack).

    I wanted to do this so that I could

    @#ifndef TIMER_H
    #define TIMER_H

    #include <QWidget>
    #include <QTimer>
    #include <QDebug>

    class Timer : public QWidget
    {
    Q_OBJECT

    public:
    Timer(QWidget *parent = 0);
    ~Timer();

    public slots:
    void Update();
    void Restart();

    private:
    QTimer *timer;
    int TimeInterval = 1000;
    int PulseCount = 0;
    };

    #endif // TIMER_H
    @

    @#ifndef WIDGET_H
    #define WIDGET_H

    #include <QWidget>
    #include <QPushButton>

    #include "timer.h"

    class Widget : public QWidget
    {
    Q_OBJECT
    public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    signals:

    public slots:

    private:
    QPushButton *button1;
    Timer *Timestamp;

    };

    #endif // WIDGET_H@

    @#include "timer.h"
    #include "widget.h"
    #include <QApplication>
    #include <QPushButton>

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

    return a.exec&#40;&#41;;
    

    }
    @

    @#include "timer.h"

    Timer::Timer(QWidget *parent)
    : QWidget(parent)
    {
    timer = new QTimer(this);
    connect(timer,&QTimer::timeout, this, &Timer::Update);
    timer->start(TimeInterval);
    }

    Timer::~Timer()
    {

    }

    void Timer::Restart()
    {
    timer->stop();
    timer->start(TimeInterval);
    PulseCount = 0;

    }

    void Timer::Update()
    {
    qDebug() << PulseCount++;
    if(PulseCount > 3)
    {
    qDebug() << "Error 3 pulses have happened";
    PulseCount = 0;

    }
    

    }

    @

    @#include "widget.h"

    Widget::Widget(QWidget *parent) :
    QWidget(parent)
    {
    // Timestamp = new Timer(this);
    button1 = new QPushButton(this);

    connect(button1,&QPushButton::clicked,Timestamp,&Timer::Restart);
    //connect(button1,SIGNAL(clicked()),Timestamp,SLOT(Restart()));
    

    }

    Widget::~Widget()
    {

    }
    @


  • Lifetime Qt Champion

    Hi

    @
    {
    // Timestamp = new Timer(this); << Timestamp is not created
    button1 = new QPushButton(this);

    connect(button1,&QPushButton::clicked,Timestamp,&Timer::Restart); << Timestamp doesn't exist
    //connect(button1,SIGNAL(clicked()),Timestamp,SLOT(Restart()));
    

    }@



  • But I thought Objects pointers place on the stack would be visible to the life of that class, so thought Timestamp in my widget constructor would still be in scope. When i set timestamp in the Widget header file as:

    @Timer Timestamp;@

    then in the connect function of Widget.cpp i just type:

    @connect(button1,&QPushButton::clicked,&Timestamp,&Timer::Restart);@

    Which works fine , But if i use:

    @Timer *Timestamp;@

    and

    @connect(button1,&QPushButton::clicked,Timestamp,&Timer::Restart);@

    The program crashes, whats actually happening here ?

    And that line your pointing to was commented out cause tried the same method of creating an object pointer in the class header file but instead pushing it onto the heap(which works fine) which isn't what i want really.


  • Lifetime Qt Champion

    @Timer *Timestamp;@

    You have an uninitialized pointer to a Timer object which is not the same as having an object. Until you initialize it to an allocated object, you just have a pointer that point to some place somewhere in the memory.



  • Ah fail, knew it was something stupid but just couldn't see what I was doing wrong.

    So should I be doing something like this in the widget header file, or is this a no-no (it does work though).

    @ Timer Timestamp;
    Timer *Timestamppoint = &Timestamp;@

    If I changed "Timestamppoint" to a shared pointer can you see any problems that I would hit, as would like to be able to access the Timestamp object from multiple classes.


  • Lifetime Qt Champion

    You are starting to slip on a nasty road.

    Don't use that even if compiles and work, that pointer adds nothing but clutter to your code (and I'm not sure all compilers will be happy).

    From where would you like to access it ? For what ?



  • OK thanks man yea did seem like I was doing something dangerous.

    Well once i've finished Timer it will contain a load of different outputs of the timer, it will have a show_time method for example, something like below but instead of grabbing currenttime it shall grab the value of the Qtimer (along with things like how many pulses have happened since the last socket comms message).

    @QString MainWindow::show_time()
    {
    QTime Current_Time = QTime::currentTime();
    Time_In_Ms = Current_Time.toString("hh:mm:ss:z");
    Time_In_S = Current_Time.toString("hh:mm:ss");
    //qDebug() << "Current Time is =" << Time_In_Ms;
    Timestamp->setText(Time_In_S);
    return Time_In_Ms;
    }@

    Along with a few other things like how many pulses have been hit since 10 seconds ago that were a certain message etc .

    Also would like this class to Emit a few signals when the timer hits certain values, which means at some point I'll have to make this class async/threaded.

    Essentially trying to just create a Timer class that can be used whenever I need to output that Timer object to another class (for example have two parts of the programs a GUI and a CCTV program, which both need to use the same object of Timer class so that they are both have a timer in sync with each other).

    Btw thanks for the help so far.


  • Lifetime Qt Champion

    Then you should maybe consider the singleton pattern for that


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.