1

I create a lambda function to run code in a different thread or simply to run it a bit later, but it can happen that an object kept by the lambda function is deleted in the mean time.

How can I detect that and not run the function in that case?

for instance

class A
{
public:
    A(){}
    virtual void test(){std::cout << m;}
    int m;
};
int main()
{
    A* a = new A();
    std::function<void ()> function = [=]()->void
    {
        //if( pointer to 'a' still valid )
        {
            a->test();
        }
    };
    delete a;
    //or if( pointer to 'a' still valid )
    function();

    system("pause");
    return 0;
}

or the detection could be done before executing the lambda function too.

An other idea is to have an object "Runnable" keep the lambda function and register it to the one that can be deleted. Then in the destructor I would notify the Runnable and prevent the execution.

Would that be a good way to do it ?

9
  • 3
    Do not use raw pointers, and use shared_ptr instead. Commented Mar 5, 2013 at 21:34
  • 1
    You should be setting a=NULL after you invoke delete. Then you can do if (a != NULL) DO SOMETHING. Commented Mar 5, 2013 at 21:37
  • using a shared ptr would keep the object alive until the execution, but I need that object to be deleted when required. Setting the variable to null doesnt change the value inside the lambda function Commented Mar 5, 2013 at 21:43
  • 4
    you can also use std::weak_ptr to have a pointer that can be checked if you have other pointers to this object and convert to smart pointer when needed (and fails graceully, if an object was deleted in the mean time, you need to use it with smart_ptr's, not raw pointers though. weak_ptr Commented Mar 5, 2013 at 21:43
  • @Tuxdude would that work? Doesn't the lambda have a copy? Commented Mar 5, 2013 at 21:58

2 Answers 2

2

You cannot test whether the object pointed by the pointer has been deleted or not..

If it has been deleted, your test() would just have undefined behavior.

Sign up to request clarification or add additional context in comments.

Comments

0

Here is a solution:

std::shared_ptr<A> a(new A());
std::weak_ptr<A> weak_a(a);
std::function<void ()> function = [weak_a]()->void
{
    if( std::shared_ptr<A> a = weak_a.lock() )
    {
        // to get the A* from a, do a.get()
        // operator-> and *a work however:
        a->test();
    }
};
a.reset(); // instead of delete

The use of the weak_ptr is optional -- if you instead made it a shared_ptr copied to the lambda, the lifetime of a would be extended by the lifetime of the lambda.

This does require that the code that uses a outside of the lambda be shared_ptr compliant.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.