December 20, 2010

poporacer poporacer
Lab Rat
59 posts

Crash-Segmentation fault

 

Let me see if I can somehow make this clear. I have a mainwindow widget with a stacked widget. Each stack of the stacked widget is a class that is loaded when the mainwindow is constructed. I have a combo box on two of the stacked widgets that I need to sychronize.
The problem seems to be that the pointer to the ui class of the second stacked widget gets lost (this is my guess, maybe not even a good guess).

In the class for the second stacked widget, I can access the ui classes and manipulate them sucessfully until I call this from the other stacked widget, then I get the segmentation fault. The method gets called sucessfully but it seems like the pointer to the method gets lost. The method can be called sucessfully from mainwindow widget but when called from namepage widget it creates the segmentation fault.
Here is the relevant code:
mainwindow.cpp

  1. #include <QtSql>
  2. #include <QSqlError>
  3. #include <QDebug>
  4. #include <QtGui>
  5. #include "namepage.h"
  6. #include "mainwindow.h"
  7. #include "ui_mainwindow.h"
  8. #include "database.h"
  9. #include "projectpage.h"
  10.  
  11. MainWindow::MainWindow(QWidget *parent) :
  12.     QMainWindow(parent),
  13.     ui(new Ui::MainWindow)
  14. {
  15.     ui->setupUi(this);
  16.     name=new NamePage(this);
  17.     project = new ProjectPage(this);
  18.     ui->MainStackWidget->setCurrentIndex(0);
  19.     ui->MainStackWidget->addWidget(name);
  20.     ui->MainStackWidget->addWidget(project);
  21.     readSettings(); //this reads the last used id from the names in the database
  22.  
  23. void MainWindow::readSettings()
  24.    {
  25.     QSettings settings ("QT Test","Project Manager");
  26.     int indexId=settings.value("lastName",0).toInt();
  27.     name->restoreName(indexId);
  28.     project->restoreName(indexId); //this call here works!
  29.    }
  30. }

namepage.cpp
  1. #include <QtGui>
  2. #include <QtSql>
  3. #include "namepage.h"
  4. #include "ui_namepage.h"
  5. #include "projectpage.h"
  6.  
  7. NamePage::NamePage(QWidget *parent) :
  8.     QWidget(parent),
  9.     ui(new Ui::NamePage)
  10. {
  11.     ui->setupUi(this);
  12.     }
  13.  
  14.  void NamePage::restoreName(int id)
  15.     {
  16.     if (id>=0)
  17.         {
  18.         int index = ui->cmbName->findData(id);
  19.         ui->cmbName->setCurrentIndex(index);
  20.         }
  21.     else
  22.         {
  23.     ui->cmbName->setCurrentIndex(0);
  24.         }
  25. }
  26. void NamePage::on_cmbName_currentIndexChanged()
  27. {
  28.    project->restoreNameCombo(ui->cmbName->itemData(ui->cmbName->currentIndex()).toInt());//this call will create segmentation fault.
  29. }

projectpage.cpp
  1. #include <QDate>
  2. #include <QtGui>
  3. #include <QtSql>
  4. #include <QDebug>
  5. #include "projectpage.h"
  6. #include "ui_projectpage.h"
  7. #include "namepage.h"
  8.  
  9. ProjectPage::ProjectPage(QWidget *parent) :
  10.     QWidget(parent),
  11.     ui(new Ui::ProjectPage)
  12. {
  13.     ui->setupUi(this);
  14.     name=new NamePage;
  15.     ui->lblDate->setText(QDate::currentDate ().toString());//this ui class reference works
  16.     updateNameComboBox();
  17. }
  18. void ProjectPage::updateNameComboBox()
  19. {
  20.  
  21.     QSqlQuery query; //all appropriate references were previously implemented not shown for brevity
  22.     query.exec("SELECT id,LName, FName FROM name");
  23.     ui->cmbSecName->blockSignals(true);
  24.     ui->cmbSecName->clear();
  25.  
  26.  
  27. while (query.next())
  28.     {
  29.      ui->cmbSecName->addItem(query.value (2).toString()+ " "
  30.                               + query.value (1).toString(),query.value (0).toInt());
  31.      ui->cmbSecName->blockSignals(false);
  32.  
  33.     }// the above ui methods work
  34. }
  35. void ProjectPage::restoreNameCombo(int cmbId) //this is where the problem lies
  36. //if called from mainwindow it works, if called from namepage, it creates a segmentation fault
  37. {
  38.     if (cmbId>=0)
  39.     {
  40.         int cmbIndex=ui->cmbSecName->findData(cmbId);
  41.         ui->cmbSecName->setCurrentIndex(cmbIndex);
  42.     }
  43.     else
  44.     {
  45.         ui->cmbSecName->setCurrentIndex(0);
  46.     }
  47. }

What is the problem?

14 replies

December 20, 2010

Milot Shala Milot Shala
Lab Rat
396 posts

Can you post your namepage.h? maybe you forgot to instantiate the project variable. I don’t see it being constructed on the constructor either.

December 20, 2010

Gerolf Gerolf
Robot Herder
3235 posts

poporacer, how do you initialize NamePage::project ? Is this pointer valid?

In ProjectPage you create a second NamePage object? Does it make sense? You do not access the one from the MainWindow here.

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

December 20, 2010

Volker Volker
Ant Farmer
5428 posts

In method NamePage::on_cmbName_currentIndexChanged() you call on member project. This seems not to be initialized.

I assume this should hold a pointer to the project member of your MainWindow class. This is not true, as you never set this variable in NamePage and it is not automatically assigned from the value of MainWindow (why should it be?).

Also, you should strongly consider using your own signals and slots to change the other combobox. NamePage should know nothing about the internals of ProjectPage and vice versa. It is generally considered wrong programming style in Qt to directly manipulate the controls of one widget class from another one.

December 21, 2010

poporacer poporacer
Lab Rat
59 posts

Here is my namepage.h

  1. #ifndef NAMEPAGE_H
  2. #define NAMEPAGE_H
  3. #include <QWidget>
  4. class ProjectPage;
  5.  
  6. namespace Ui {
  7.     class NamePage;
  8. }
  9.  
  10. class NamePage : public QWidget
  11. {
  12.     Q_OBJECT
  13.  
  14. public:
  15.     explicit NamePage(QWidget *parent = 0);
  16.     ~NamePage();
  17.     void restoreName(int);
  18.     int getLastName();
  19.    
  20. private:
  21.     Ui::NamePage *ui;
  22.         NamePage *name;
  23.         ProjectPage *project;
  24.         void updateNameComboBox();
  25.  
  26.     };
  27.  
  28. #endif // NAMEPAGE_H

Do you see anything wrong here? I think the pointer is a valid one?
Gerolf, I created another NamePage object because I was going to pass some information from the projectpage to the namepage…I think I will change that to use signals and slots.
I think I will change the code to use signals and slots as soon as I get some free time.
Volker, I am still trying to figure out the signals and slots syntax to address one class to another. I will try to change this!
I really appreciate all of your assistance.

December 21, 2010

Gerolf Gerolf
Robot Herder
3235 posts

If you create a new instance of NamePage, you are changing the new instance, not the one inside MainWindow. You have to pass the pointer to the existing NamePage to ProjectPage or use signal/slot. Otherwise the two pages do not communicate .

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

December 21, 2010

Volker Volker
Ant Farmer
5428 posts

Additionally, you do not pass any pointer of a ProjectPage to the NamePage. The ProjectPage *project pointer is uninitialized, accessing it will always cause a crash!

December 21, 2010

Gerolf Gerolf
Robot Herder
3235 posts

Not always cause a crash Volker, the behavior is undefined, or how we say here: you could create an earthquake :-) If you are lucky, it crashes, otherwise no one knows what happens….

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

December 21, 2010

Bobs Bobs
Lab Rat
34 posts

You’re very lucky it crashed. No, really.

We’ve had an incident some time ago: one of our products (installed in about 1000 offices all over the country) started to get mad and do a strange things after some months of stable working. The problem was in uninitialized pointer of course. But it really worked fine for a while and passed through QA department, some automated stress-test and a months in a production before we had this bug in a one happy day.

 Signature 

Nokia Certified Qt Specialist.

December 21, 2010

Gerolf Gerolf
Robot Herder
3235 posts

That’s why I said, you are happy if it crashes, because you find it…
If it doesn’t crash it gets complicated, like you described…

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

December 22, 2010

poporacer poporacer
Lab Rat
59 posts

Thanks for all the help! I am pretty new at C++ and Qt programming and I am reading and trying all I can to better understand. I am still a bit confused… Gerolf, you stated that if I create a new instance of NamePage, I am changing the new instance. I don’t quite understand. I created a new instance for a new class. I guess this is not the correct way? And then you say that I need to pass the pointer to the existing NamePage to ProjectPage. I am not sure how to do that. Could you give me an example of how to do that?
Volker, You stated that I did not pass a pointer of ProjectPage to the NamePage and that the ProjectPage *project pointer is uninitialized. I thought that by delaring a ProjectPage class in the header of NamePage and a pointer “ProjectPage *project” in the NamePage header took care of this.
I am going to rewrite this to use signals and slots, I kinda understand how to do this between classes, so I will give it a try.
But my question now is (and this is just for knowlege in case I run accross a similiar situation) How do you go about passing pointers and would it work if I instantiate a pointer to each class in MainWindow and pass the pointer around? And what is the method to do that.
Again, Thanks for your advice and I will post back after I change the code for signals and slots and see if I can get it to work!

December 22, 2010

Gerolf Gerolf
Robot Herder
3235 posts

Hi poporacer,

passing the pointer would solve your problem (which is a C++, not a Qt problem) or using signals / slots.

What I meant with

you stated that if I create a new instance of NamePage, I am changing the new instance.

If you have

  1.  1 class A
  2.  2 {
  3.  3     A()
  4.  4     {
  5.  5         m_p2 = new B;
  6.            m_bNotified = false;
  7.  6     }
  8.  7     foo1()
  9.  8     {
  10.  9         m_p2->foo();
  11. 10     }
  12. 11     notify(){m_bNotified = true};
  13. 11a    notified(){return m_bNotified};
  14. 11b    B* m_p2;
  15. 12 }
  16. 13
  17. 14 class B
  18. 15 {
  19. 16     foo()
  20. 17     {
  21. 18         m_p3 = new A;
  22. 19         m_p3->notify();
  23. 20     }
  24. 20a    A* m_p3;
  25. 21 }
  26. 22
  27. 23 main(...)
  28. 24 {
  29. 25     A* m_p1 = new A;
  30. 26     m_p1->foo1();
  31. 27     m_p1->notified(); // will return false !!!
  32. 28 }

If you call on line 26 the instance m_p1->foo, on line 18 you create a new instance of A and the notify (line 19)will not arrive at object m_p1 but m_p3 as you have 2 instances. You do the same in your code. m_p1 != m_p3 so if you go back to main and call notified on m_p1, it will return false, as m_p3 is notified, not m_p1.

[EDIT: fixed blockquote tag, Volker]
[EDIT: added Variable types, Gerolf]

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

December 22, 2010

Volker Volker
Ant Farmer
5428 posts

Gerolf, m_p1 is of type, there is no foo in that class…?

December 22, 2010

Gerolf Gerolf
Robot Herder
3235 posts

Ok, ok, I let the types out:-) I will add them in the original post
And it should be foo1(), it was pseudo code, not tested in compiler. It would have found it…

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

December 22, 2010

Volker Volker
Ant Farmer
5428 posts

Regarding your pointer problems, see my answer [developer.qt.nokia.com] in your signals/slots thread.

 
  ‹‹ Unable to display items of QListWidget      QPainter JNI call crashes the application ››

You must log in to post a reply. Not a member yet? Register here!