Results 1 to 13 of 13

Thread: Signals destroys my pointer

  1. #1
    Join Date
    Feb 2006
    Posts
    24
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Signals destroys my pointer

    Hello,

    I have an odd problem with one of my signals. This is one of the problems where everything used to work yesterday, but now it doesn't.

    The problem occurs when I pass a structure by pointer over an interface, when I read the variable in a slot the contents are all garbage.

    This is what I'm doing (hope you don't mind reading some code for problem solving :
    I am handling a find text functionality, the user pressd a button, the find text dialog triggers a signal, the controller does the search..

    Qt Code:
    1. // This function emits the problematic signal
    2. void findTextDialog::onFindButtonSlot ()
    3. {
    4. // setup find text event args from dialog
    5. interfaces::eventArgs::findTextEventArg args;
    6. args._findString = ui.findStringTextbox->text();
    7. args._caseSensitive = (ui.matchCaseCheckBox->checkState() == Qt::Checked);
    8. args._wholeWord = (ui.wholeWordCheckbox->checkState() == Qt::Checked);
    9. args._backwards = (ui.findBackwardsCheckbox->checkState() == Qt::Checked);
    10.  
    11. // This output is all right..
    12. LOG_ERROR (QString("VIEWFIND:1").arg(ui.findStringTextbox->text()).toStdString());
    13.  
    14. // trigger event in interface
    15. emit interface.onFindTextSignal (&args);
    16. }
    17.  
    18. // The interface signal:
    19. class interface
    20. {
    21. // This is triggered in the dialog and connected to in the controller
    22. void onFindTextSignal (interfaces::eventArgs::findTextEventArg* searchParameter);
    23. }
    24.  
    25. // The controller slot handling the finding:
    26. void findReplaceController::findTextSlot (interfaces::eventArgs::findTextEventArg* arg)
    27. {
    28. LOG_ERROR ("BEFORE");
    29.  
    30. // This gives me garbage OR a crash
    31. LOG_ERROR (QString("SEARCHSTRING: %1").arg(arg->_findString).toStdString());
    32. }
    33.  
    34. // The structure I am passing
    35. struct findTextEventArg
    36. {
    37. //! Search parameters
    38. QString _findString;
    39. bool _caseSensitive;
    40. bool _backwards;
    41. bool _wholeWord;
    42. };
    To copy to clipboard, switch view to plain text mode 


    I hope you can help me with this problem. This code used to work a couple of days ago and I can't see nothing wrong with it. Passing custom types via pointer over interfaces works fine.
    The connections are not queued or anything, I don't even get a Qt warning.


    Thanks for your help

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Signals destroys my pointer

    Qt Code:
    1. emit interface.onFindTextSignal (&args);
    To copy to clipboard, switch view to plain text mode 

    Hmm... why do you emit.... a method (returning "void" to be even more funny)? Or am I wrong? We don't see any variable declarations, it's hard to say what do you do there at all. I don't see any QObjects or nothing. Are you using Qt signals at all?

  3. #3
    Join Date
    Feb 2006
    Posts
    24
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Signals destroys my pointer

    Hello,

    thanks for your reply!

    Of course I am using signals and stuff, I just left out the least important bits of information. Of course the interface function is a signal too, I just left it out because I didn't want to spam this topic.

    If you say you don't understand what I am doing let me explain it to you quickly:
    As said before, I have implemented a "find text" dialog, which allows you to search for text in a QTextEdit.
    The first class (findTextDialog) handles the gui stuff of the dialog. The function/slot I have pasted is the slot which gets executed when the user presses the "&Find" button.
    The function onFindButtonSlot then emits a signal on an interface.
    The interface is a common place where signals for view<->controller interactions are saved. This might seem a little odd at first glance, but it is called a hexagonal MVC pattern, there is no direct contact between view and controller clases at all.
    The controller class findReplaceController connects to the specific interface signals when the application starts. It also receives the "find text" signal emitted from the find text dialog.
    As parameter some eventargs are passed. This structure saves information about what to search as well as some search options. It is this variable which gets corrupted during transfer over the signals. Like I mentioned before, this is odd because it used to work yesterday (c).
    I hope with these explanations and with the new code my problem makes more sense to you than it does to me now

    Ok, let's start with a more verbose code dump :

    FindTextDialog - The one who emits the signal..
    Qt Code:
    1. class findTextDialog : public QDialog
    2. {
    3. Q_OBJECT
    4.  
    5. //
    6. void onFindButtonSlot ()
    7. {
    8. LOG_DEBUG("findTextDialog::onFindButtonSlot");
    9.  
    10. // setup find text event args from dialog
    11. interfaces::eventArgs::findTextEventArg args;
    12. args._findString = ui.findStringTextbox->text();
    13. args._caseSensitive = (ui.matchCaseCheckBox->checkState() == Qt::Checked);
    14. args._wholeWord = (ui.wholeWordCheckbox->checkState() == Qt::Checked);
    15. args._backwards = (ui.findBackwardsCheckbox->checkState() == Qt::Checked);
    16.  
    17. LOG_ERROR (QString("VIEWFIND: %1").arg(ui.findStringTextbox->text()).toStdString());
    18. // trigger event in interface
    19. emit getFindTextInterface().onFindTextSignal (&args);
    20.  
    21. // close dialog
    22. onCancelButtonSlot ();
    23. }
    24. };
    To copy to clipboard, switch view to plain text mode 


    The interface - This class stores some signals which controller and view use to communicate
    Qt Code:
    1. class findTextInterface : public QObject, public genericInterface
    2. {
    3. Q_OBJECT
    4.  
    5. signals:
    6.  
    7. //! Signals sent FROM the view TO the controller
    8.  
    9. /// Start searching for some text.. sent by the find button of the find text dialog
    10. void onFindTextSignal (interfaces::eventArgs::findTextEventArg* searchParameter);
    11. };
    To copy to clipboard, switch view to plain text mode 


    FindReplaceController - This is the class which should take care of doing the "find text" logic
    Qt Code:
    1. /**
    2. @brief Controller class to select(find) and replace text
    3. */
    4. class findReplaceController : public QObject, public genericController
    5. {
    6. Q_OBJECT
    7. virtual void connectSignals ()
    8. {
    9. // find text
    10. connect (getFindTextInterface(),
    11. SIGNAL(onFindTextSignal(interfaces::eventArgs::findTextEventArg*) ),
    12. this, SLOT(findTextSlot(interfaces::eventArgs::findTextEventArg*)));
    13.  
    14. }
    15.  
    16. public slots:
    17. /**
    18. @brief Called from the view, this finds some text in the front file in the editor
    19. */
    20. void findTextSlot interfaces::eventArgs::findTextEventArg* arg)
    21. {
    22. // This crashes sometimes or gives bad data
    23. LOG_ERROR (QString("SEARCHSTRING: %1").arg(arg->_findString).toStdString());
    24.  
    25. }
    26. };
    To copy to clipboard, switch view to plain text mode 


    FindTextEventArgs - This is passed over the interface from the view
    Qt Code:
    1. struct findTextEventArg
    2. {
    3. //! Search parameters
    4. QString _findString;
    5. bool _caseSensitive;
    6. bool _backwards;
    7. bool _wholeWord;
    8. };
    To copy to clipboard, switch view to plain text mode 


    Thanks for help and replies,
    Bye, Headhunter

    (Hope the forum doesn't kill my beautiful code intendention)

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Signals destroys my pointer

    Quote Originally Posted by Jojo
    Of course I am using signals and stuff, I just left out the least important bits of information.
    Or the most important ones.

    Of course the interface function is a signal too, I just left it out because I didn't want to spam this topic.
    (...)
    The function onFindButtonSlot then emits a signal on an interface.
    The interface is a common place where signals for view<->controller interactions are saved.
    You can't emit signals from other objects. You have to provide wrappers, like so:
    Qt Code:
    1. class someclass : public QObject{
    2. Q_OBJECT
    3. public:
    4. void emitSignal1(){ emit signal1(); }
    5. void emitSignal2(){ emit signal2(); }
    6. signals:
    7. void signal1();
    8. void signal2();
    9. //...
    10. };
    To copy to clipboard, switch view to plain text mode 

    This might seem a little odd at first glance, but it is called a hexagonal MVC pattern, there is no direct contact between view and controller clases at all.
    As far as I understand, Qt signals/slots do just that on their own.

    The controller class findReplaceController connects to the specific interface signals when the application starts. It also receives the "find text" signal emitted from the find text dialog.
    (...)
    You are making it very complex... too complex, I think.

    If you have to make things complex (but still working), a signal proxy might help you. One of the issues of Qt Quarterly describes that.

    (Hope the forum doesn't kill my beautiful code intendention)
    Don't worry, the forum didn't kill anything yet, so it won't kill your indentation.

  5. #5
    Join Date
    Feb 2006
    Posts
    24
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Signals destroys my pointer

    Hello,

    I know the hexagonal MVC pattern is a bit heavy.. but that's the way I decided to go, and it actually works out quite fine.
    I don't need signal proxys, because (don't hit me) I "#define protected public" before each signal. Works fine, and I don't need emitters.
    But do you have any ideas about the problem?

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Signals destroys my pointer

    Quote Originally Posted by Jojo
    I don't need signal proxys, because (don't hit me) I "#define protected public" before each signal. Works fine, and I don't need emitters.
    This behaviour is not documented anywhere (meaning its implementation dependent), so one day your code might just stop working.

    But do you have any ideas about the problem?
    I'll ask my question again Why don't you use references instead of pointers?
    Qt Code:
    1. void onFindTextSignal (interfaces::eventArgs::findTextEventArg &searchParameter);
    To copy to clipboard, switch view to plain text mode 

    BTW. Are the emitter and receiver in the same thread? Which Qt version are you using?

  7. #7
    Join Date
    Feb 2006
    Posts
    24
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Signals destroys my pointer

    Hello,

    thanks for your answer.
    I am using pointers because passing by reference does not work. QObject gives me a warning at runtime, telling me the parameter can not be queued. Registering my custom type to the Qt Metasystem should work, but it doesn't. So I use pointers.
    This problem occurs with Qt 4.1.0 and with the previous version too.
    I use a single threaded application, the signals are not queued either.
    Odd, isn't it ?

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Signals destroys my pointer

    Quote Originally Posted by Jojo
    Registering my custom type to the Qt Metasystem should work, but it doesn't.
    What errors do you get?

  9. #9
    Join Date
    Jan 2006
    Posts
    132
    Thanked 16 Times in 16 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Signals destroys my pointer

    What you are trying to do will obviously fail when the signal is queued. You are creating an object 'args' within the method 'onFindButtonSlot' and sending it's address by the signal. However that object is deleted at the end of 'onFindButtonSlot' and when your queued signal is processed later it is allready destroyed.

  10. The following user says thank you to seneca for this useful post:

    Jojo (7th March 2006)

  11. #10
    Join Date
    Feb 2006
    Posts
    24
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Cool Re: Signals destroys my pointer

    Hello,

    I have set the signal explicitly to a direct connection, and now my search function works like a charm. I really can't explain why, I am not using threads, and I am always calling connect without any extra connection type parameters.

    Now I have another problem. My application will terribly crash if signal connections are not direct. I haven't noticed any strange crash yet, but who knows.

    What shall I do now? Explictly set DirectConnection to each connect line? Set a nondocumented flag in QApplication to disable implicit multithreading? I'm again very clueless about Qt's behaviour..

    Thanks for advice again

  12. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Signals destroys my pointer

    Don't use pointers to temporary objects. Either make those structures heap based or don't use pointers at all. I'm still curious what errors did you get while trying to use a reference... Maybe you forgot the magic "const" keyword? It is possible if you wanted to reference a temporary object.

  13. #12
    Join Date
    Feb 2006
    Posts
    24
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Wink Re: Signals destroys my pointer

    Quote Originally Posted by wysota
    Don't use pointers to temporary objects. Either make those structures heap based or don't use pointers at all. I'm still curious what errors did you get while trying to use a reference... Maybe you forgot the magic "const" keyword? It is possible if you wanted to reference a temporary object.
    Hello,
    I need pointers to objects. As I said before, passing custom types over signals only works when I pass them via pointer.
    I don't think passing the pointer as const would help much. As far as I see it, Qt signal parameters are passed by value just like in Java or in .NET. I can't see a constant pointer help much there.
    Passing a pointer for a temporary object is fine in my case, because the controller creates a copy of the passed object, so the temporary object pointer is only accessed once, when the object is still well defined.

    I don't get any errors when accessing the passed pointer. Since when tells C++ errormessages when you do something wrong
    What happens is, that the received pointer is garbage.
    Use "int* a; int b = *a+4" for a similar experience. Either your programm crashes or you receive some weird values..

    Still the question remains, why does Qt make my signal calls asynchronous? This is poison for my application!

  14. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Signals destroys my pointer

    Quote Originally Posted by Jojo
    As I said before, passing custom types over signals only works when I pass them via pointer.
    But what does "not work" mean?

    I can't see a constant pointer help much there.
    I meant a constant reference.

    Passing a pointer for a temporary object is fine in my case, because the controller creates a copy of the passed object, so the temporary object pointer is only accessed once, when the object is still well defined.
    Not with asynchronous calls.

Similar Threads

  1. Dragging a pointer
    By Cruz in forum Qt Programming
    Replies: 4
    Last Post: 10th July 2009, 03:51
  2. Signals are delayed on X11?
    By Cruz in forum Qt Programming
    Replies: 13
    Last Post: 18th February 2009, 12:59

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.