What will this do?

Started by
5 comments, last by ville-v 15 years, 4 months ago
I'm just getting into signals and slots after learning about them through the Qt library. I'm playing around with boost::signal and must admit, it's pretty cool. Anyway, I've got a question. Let's say I've got a slot that's a member of a class (or struct). If I connect an object's member function to a signal, and then the object gets destroyed, what happens? I've run it and it appears to work, but I don't know if this is just undefined behavior or if it is actually supposed to work. It's kind of hard to explain my question without some code, so this is an example of what I'm talking about:
#include <boost/bind.hpp>
#include <boost/signal.hpp>
#include <iostream>

struct MyStruct
{
    void printInt(int i)
    {
        std::cout << "printInt: " << i << std::endl;
    }
};

int main()
{
    boost::signal<void (int)> sig;
    
    {
        MyStruct myObject;
        sig.connect(boost::bind(&MyStruct::printInt, &myObject, _1));
    }
    
    sig(5); // myObject was destroyed, but it still calls printInt and prints 5.
            // Why does it do that if myObject has been destroyed?  Is it
            // undefined behavior, or is myObject preserved and is this valid?
            // What happens under the hood after myObject is destroyed?
}
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Advertisement
It's undefined behaviour.
It works for now since your function does not access any instance specific data. If it would try to access instance data it would probably crash right away.
This seems to work since most compiler implement member functions as global functions with an implicit this pointer. And it works because you do not access the this pointer.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Thanks for the quick reply! I thought it might be undefined behavior but I wasn't sure. But it's good to know now!
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
You can make MyStruct trackable if you want it automatically disconnect when it gets destroyed.
Quote:Original post by Kambiz
You can make MyStruct trackable if you want it automatically disconnect when it gets destroyed.


Is that what the trackable class is for? I saw it and was wondering what it was but figured it was some internal boost thing. So in the above example, if I wanted myObject to automatically disconnect upon its destruction, all I have to do is make MyStruct inherit from trackable and that's it? I just ran the example with MyStruct deriving from trackable and printInt was never called, so it appears to work just fine, but I want to make sure I'm using it correctly.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Quote:Original post by MikeTacular
Quote:Original post by Kambiz
You can make MyStruct trackable if you want it automatically disconnect when it gets destroyed.


Is that what the trackable class is for? I saw it and was wondering what it was but figured it was some internal boost thing. So in the above example, if I wanted myObject to automatically disconnect upon its destruction, all I have to do is make MyStruct inherit from trackable and that's it? I just ran the example with MyStruct deriving from trackable and printInt was never called, so it appears to work just fine, but I want to make sure I'm using it correctly.


Yes, thats what the trackable class is for. But it has some limitations, read the warning under "Automatic connection management".
Quote:Original post by MikeTacular
I'm just getting into signals and slots after learning about them through the Qt library. I'm playing around with boost::signal and must admit, it's pretty cool. Anyway, I've got a question. Let's say I've got a slot that's a member of a class (or struct). If I connect an object's member function to a signal, and then the object gets destroyed, what happens? I've run it and it appears to work, but I don't know if this is just undefined behavior or if it is actually supposed to work. It's kind of hard to explain my question without some code, so this is an example of what I'm talking about:


After myObject gets destroyed pointer that is saved somewhere in sig (I do not really know how that class works) will point to invalid memory. You call function of MyStruct, not myObject, so this-pointer is not needed anywhere. If function would use this, access violation would happen and your program would crash.

Similar example:
class a{ function(); };a *b = new a();b->function(); // Worksb = NULL;b->function(); // Does not worka *c;c->function(); // Might work or might not

This topic is closed to new replies.

Advertisement