Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Confusion about this pointer and callback functions

Let’s say I have the following scenario where I define a callback function m_deleter.


class B {
public:
    B() = default;
    ~B(){
        if (m_deleter) {
            m_deleter();
        }
    }

    std::function<void()> m_deleter = nullptr;
};

class A {
public:
    void createB(B& b) {
        auto func = [this]() {
            this->printMessage();
        };

        b.m_deleter = func;
    }

    void printMessage() {
        std::cout << "Here is the message!" << std::endl;
    }
};

And here is our main function:

int main() {
    B b;

    {
        A a;
        a.createB(b);
    } // a falls out of scope.

}

Here is my confusion. When the stack instance a falls out of scope, is the memory not deallocated? How can the this pointer, used here in the callback: this->printMessage(); still point to a valid object?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

When I run the above program, it prints:
Here is the message!

Edit:
Follow up question, is there any way for b to know that a has fallen out of scope and is no longer a valid object, and therefore should not call the callback?

>Solution :

It doesn’t. But due to the fact that in the method printMessage you don’t reference any fields from the class A, there is no crush. This is an UB however.

Here is the code that avoids this issue but demonstrates the correct behavior:

class A {
public:
    void createB(B& b) {
        auto func = []() {
            A::printMessage();
        };

        b.m_deleter = func;
    }

    static void printMessage() {
        std::cout << "Here is the message!" << std::endl;
    }
};

No pointer, no references to any field, no need to track whether the instance is valid, no UB. If you need to access the data from A, you need a valid instance.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading