How can I pass an object's member variable (field) as a reference to a thread safely? - c++

Let's say I start a new thread from a classmethod and pass "this" as a parameter to the lambda of the new thread. If the object is destroyed before the thread uses something from "this", then it's probably undefined behavior.
As a simple example:
#include <thread>
#include <iostream>
class Foo
{
public:
Foo() : m_bar{123} {}
void test_1()
{
std::thread thd = std::thread{[this]()
{
std::cout << m_bar << std::endl;
}};
thd.detach();
}
void test_2()
{
test_2(m_bar);
}
void test_2(int & bar)
{
std::thread thd = std::thread{[this, & bar]()
{
std::cout << bar << std::endl;
}};
thd.detach();
}
private:
int m_bar;
};
int main()
{
// 1)
std::thread thd_outer = std::thread{[]()
{
Foo foo;
foo.test_1();
}};
thd_outer.detach();
// 2)
{
Foo foo;
foo.test_1();
}
std::cin.get();
}
The outcomes
(For the original project, I have to use VS19, so the exception messages are originally coming from that IDE.)
Starting from thd_outer, test_1 and test_2 are either throwing an exception (Exception thrown: read access violation.) or printing 0 (instead of 123).
Without thd_outer they seem correct.
I've tried the same code with GCC under Linux, and they always print 123.
Which one is the correct behavior? I think it is UB, and in that case all are "correct". If it's not undefined, then why are they different?
I would expect 123 or garbage always because either the object is still valid (123) or was valid but destroyed and a) the memory is not reused yet (123) or reused (garbage). An exception is reasonable but what exactly is throwing it (VS only)?
I've came up with a possible solution to the problem:
class Foo2
{
public:
Foo2() : m_bar{123} {}
~Foo2()
{
for (std::thread & thd : threads)
{
try
{
thd.join();
}
catch (const std::system_error & e)
{
// handling
}
}
}
void test_1()
{
std::thread thd = std::thread{[this]()
{
std::cout << m_bar << std::endl;
}};
threads.push_back(std::move(thd));
}
private:
int m_bar;
std::vector<std::thread> threads;
};
Is it a safe solution, without undefined behaviors? Seems like it's working. Is there a better and/or more "standardized" way?

Forget about member variables or classes. The question then is, how do I make sure that a thread does not use a reference to an object that has been destroyed. Two approaches exist that both effectively ensure that the thread ends before the object is destroyed plus a third one that's more complicated.
Extend the object lifetime to that of the thread. The easiest way is to use dynamic allocation of the object. In addition, to avoid memory leaks, use smart pointers like std::shared_ptr.
Limit the thread runtime to that of the object. Before destroying the object, simply join the thread.
Tell the thread to let go of the object before destroying it. I'll only sketch this, because its the most complicated way, but if you somehow tell the thread that it must not use the object any more, you can then destroy the object without adverse side effects.
That said, one advise: You are sharing an object between (at least) two threads. Accessing it requires synchronization, which is a complex topic in and of itself.

Related

Is there a way to protect a smart pointer from being deallocated on one thread, when work is being done on another thread?

In our program, we have a class FooLogger which logs specific events (strings). We use the FooLogger as a unique_ptr.
We have two threads which use this unique_ptr instance:
Thread 1 logs the latest event to file in a while loop, first checking if the instance is not nullptr
Thread 2 deallocates the FooLogger unique_ptr instance when the program has reached a certain point (set to nullptr)
However, due to bad interleaving, it is possible that, while logging, the member variables of FooLogger are deallocated, resulting in an EXC_BAD_ACCESS error.
class FooLogger {
public:
FooLogger() {};
void Log(const std::string& event="") {
const float32_t time_step_s = timer_.Elapsed() - runtime_s_; // Can get EXC_BAD_ACCESS on timer_
runtime_s_ += time_step_s;
std::cout << time_step_s << runtime_s_ << event << std::endl;
}
private:
Timer timer_; // Timer is a custom class
float32_t runtime_s_ = 0.0;
};
int main() {
auto foo_logger = std::make_unique<FooLogger>();
std::thread foo_logger_thread([&] {
while(true) {
if (foo_logger)
foo_logger->Log("some event");
else
break;
}
});
SleepMs(50); // pseudo code
foo_logger = nullptr;
foo_logger_thread.join();
}
Is it possible, using some sort of thread synchronisation/locks etc. to ensure that the foo_logger instance is not deallocated while logging? If not, are there any good ways of handling this case?
The purpose of std::unique_ptr is to deallocate the instance once std::unique_ptr is out of scope. In your case, you have multiple threads each having access to the element and the owning thread might get eliminated prior to other users.
You either need to ensure that owner thread never gets deleted prior to the user threads or change ownership model from std::unique_ptr to std::shared_ptr. It is the whole purpose of std::shared_ptr to ensure that the object is alive as long as you use it.
You just need to figure out what's required for program and use the right tools to achieve it.
Use a different mechanism than the disappearance of an object for determining when to stop.
(When you use a single thing for two separate purposes, you often get into trouble.)
For instance, an atomic bool:
int main() {
FooLogger foo_logger;
std::atomic<bool> keep_going = true;
std::thread foo_logger_thread([&] {
while(keep_going) {
foo_logger.Log("some event");
}
});
SleepMs(50);
keep_going = false;
foo_logger_thread.join();
}
It sounds like std::weak_ptr can help in this case.
You can make one from a std::shared_ptr and pass it to the logger thread.
For example:
class FooLogger {
public:
void Log(std::string const& event) {
// log the event ...
}
};
int main() {
auto shared_logger = std::make_shared<FooLogger>();
std::thread foo_logger_thread([w_logger = std::weak_ptr(shared_logger)]{
while (true) {
auto logger = w_logger.lock();
if (logger)
logger->Log("some event");
else
break;
}
});
// some work ...
shared_logger.reset();
foo_logger_thread.join();
}
Use should use make_shared instead of make_unique. And change:
std::thread foo_logger_thread([&] {
to
std::thread foo_logger_thread([foo_logger] {
It will create new instance of shared_ptr.

How Can this == nullptr Ever be true Without Invoking Undefined Behavior? [duplicate]

Does it ever make sense to check if this is null?
Say I have a class with a method; inside that method, I check this == NULL, and if it is, return an error code.
If this is null, then that means the object is deleted. Is the method even able to return anything?
Update: I forgot to mention that the method can be called from multiple threads and it may cause the object to be deleted while another thread is inside the method.
Does it ever make sense to check for this==null? I found this while doing a code review.
In standard C++, it does not, because any call on a null pointer is already undefined behavior, so any code relying on such checks is non-standard (there's no guarantee that the check will even be executed).
Note that this holds true for non-virtual functions as well.
Some implementations permit this==0, however, and consequently libraries written specifically for those implementations will sometimes use it as a hack. A good example of such a pair is VC++ and MFC - I don't recall the exact code, but I distinctly remember seeing if (this == NULL) checks in MFC source code somewhere.
It may also be there as a debugging aid, because at some point in the past this code was hit with this==0 because of a mistake in the caller, so a check was inserted to catch future instances of that. An assert would make more sense for such things, though.
If this == null then that means the object is deleted.
No, it doesn't mean that. It means that a method was called on a null pointer, or on a reference obtained from a null pointer (though obtaining such a reference is already U.B.). This has nothing to do with delete, and does not require any objects of this type to have ever existed.
Your note about threads is worrisome. I'm pretty sure you have a race condition that can lead to a crash. If a thread deletes an object and zeros the pointer, another thread could make a call through that pointer between those two operations, leading to this being non-null and also not valid, resulting in a crash. Similarly, if a thread calls a method while another thread is in the middle of creating the object, you may also get a crash.
Short answer, you really need to use a mutex or something to synchonize access to this variable. You need to ensure that this is never null or you're going to have problems.
I know that this is old but I feel like now that we're dealing with C++11-17 somebody should mention lambdas. If you capture this into a lambda that is going to be called asynchronously at a later point in time, it is possible that your "this" object gets destroyed before that lambda is invoked.
i.e passing it as a callback to some time-expensive function that is run from a separate thread or just asynchronously in general
EDIT: Just to be clear, the question was "Does it ever make sense to check if this is null" I am merely offering a scenario where it does make sense that might become more prevalent with the wider use of modern C++.
Contrived example:
This code is completely runable. To see unsafe behavior just comment out the call to safe behavior and uncomment the unsafe behavior call.
#include <memory>
#include <functional>
#include <iostream>
#include <future>
class SomeAPI
{
public:
SomeAPI() = default;
void DoWork(std::function<void(int)> cb)
{
DoAsync(cb);
}
private:
void DoAsync(std::function<void(int)> cb)
{
std::cout << "SomeAPI about to do async work\n";
m_future = std::async(std::launch::async, [](auto cb)
{
std::cout << "Async thread sleeping 10 seconds (Doing work).\n";
std::this_thread::sleep_for(std::chrono::seconds{ 10 });
// Do a bunch of work and set a status indicating success or failure.
// Assume 0 is success.
int status = 0;
std::cout << "Executing callback.\n";
cb(status);
std::cout << "Callback Executed.\n";
}, cb);
};
std::future<void> m_future;
};
class SomeOtherClass
{
public:
void SetSuccess(int success) { m_success = success; }
private:
bool m_success = false;
};
class SomeClass : public std::enable_shared_from_this<SomeClass>
{
public:
SomeClass(SomeAPI* api)
: m_api(api)
{
}
void DoWorkUnsafe()
{
std::cout << "DoWorkUnsafe about to pass callback to async executer.\n";
// Call DoWork on the API.
// DoWork takes some time.
// When DoWork is finished, it calls the callback that we sent in.
m_api->DoWork([this](int status)
{
// Undefined behavior
m_value = 17;
// Crash
m_data->SetSuccess(true);
ReportSuccess();
});
}
void DoWorkSafe()
{
// Create a weak point from a shared pointer to this.
std::weak_ptr<SomeClass> this_ = shared_from_this();
std::cout << "DoWorkSafe about to pass callback to async executer.\n";
// Capture the weak pointer.
m_api->DoWork([this_](int status)
{
// Test the weak pointer.
if (auto sp = this_.lock())
{
std::cout << "Async work finished.\n";
// If its good, then we are still alive and safe to execute on this.
sp->m_value = 17;
sp->m_data->SetSuccess(true);
sp->ReportSuccess();
}
});
}
private:
void ReportSuccess()
{
// Tell everyone who cares that a thing has succeeded.
};
SomeAPI* m_api;
std::shared_ptr<SomeOtherClass> m_data = std::shared_ptr<SomeOtherClass>();
int m_value;
};
int main()
{
std::shared_ptr<SomeAPI> api = std::make_shared<SomeAPI>();
std::shared_ptr<SomeClass> someClass = std::make_shared<SomeClass>(api.get());
someClass->DoWorkSafe();
// Comment out the above line and uncomment the below line
// to see the unsafe behavior.
//someClass->DoWorkUnsafe();
std::cout << "Deleting someClass\n";
someClass.reset();
std::cout << "Main thread sleeping for 20 seconds.\n";
std::this_thread::sleep_for(std::chrono::seconds{ 20 });
return 0;
}
FWIW, I have used debugging checks for (this != NULL) in assertions before which have helped catch defective code. Not that the code would have necessarily gotten too far with out a crash, but on small embedded systems that don't have memory protection, the assertions actually helped.
On systems with memory protection, the OS will generally hit an access violation if called with a NULL this pointer, so there's less value in asserting this != NULL. However, see Pavel's comment for why it's not necessarily worthless on even protected systems.
Your method will most likely (may vary between compilers) be able to run and also be able to return a value. As long as it does not access any instance variables. If it tries this it will crash.
As others pointed out you can not use this test to see if an object has been deleted. Even if you could, it would not work, because the object may be deleted by another thread just after the test but before you execute the next line after the test. Use Thread synchronization instead.
If this is null there is a bug in your program, most likely in the design of your program.
I'd also add that it's usually better to avoid null or NULL. I think the standard is changing yet again here but for now 0 is really what you want to check for to be absolutely sure you're getting what you want.
This is just a pointer passed as the first argument to a function (which is exactly what makes it a method). So long as you're not talking about virtual methods and/or virtual inheritance, then yes, you can find yourself executing an instance method, with a null instance. As others said, you almost certainly won't get very far with that execution before problems arise, but robust coding should probably check for that situation, with an assert. At least, it makes sense when you suspect it could be occuring for some reason, but need to track down exactly which class / call stack it's occurring in.
I know this is a old question, however I thought I will share my experience with use of Lambda capture
#include <iostream>
#include <memory>
using std::unique_ptr;
using std::make_unique;
using std::cout;
using std::endl;
class foo {
public:
foo(int no) : no_(no) {
}
template <typename Lambda>
void lambda_func(Lambda&& l) {
cout << "No is " << no_ << endl;
l();
}
private:
int no_;
};
int main() {
auto f = std::make_unique<foo>(10);
f->lambda_func([f = std::move(f)] () mutable {
cout << "lambda ==> " << endl;
cout << "lambda <== " << endl;
});
return 0;
}
This code segment faults
$ g++ -std=c++14 uniqueptr.cpp
$ ./a.out
Segmentation fault (core dumped)
If I remove the std::cout statement from lambda_func The code runs to completion.
It seems like, this statement f->lambda_func([f = std::move(f)] () mutable { processes lambda captures before member function is invoked.

Simplest way to make std::thread exception safe

std::thread class is inherently exception-unsafe since its destructor calls std::terminate.
std::thread t( function );
// do some work
// (might throw!)
t.join();
You could, of course, put everything in between construction and join() in a try-catch block, but this can get tedious and error-prone if you know you want to join or detach no matter what happens.
So I was thinking how would one go about writing the simplest possible wrappers around it, but that would also support other hypothetical types of threads. For instance, boost::thread or something completely different, as long as it had joinable(), join() and detach() methods. Here's how far I've got:
// handles threads safely
// Acts the same as the underlying thread type, except during destruction.
// If joinable, will call join (and block!) during destruction.
// Keep in mind that any exception handling will get delayed because of that;
// it needs to wait for the thread to finish its work first.
template <class UNDERLYING_THREAD = std::thread>
class scoped_thread: public UNDERLYING_THREAD
{
public:
typedef UNDERLYING_THREAD thread_type;
using thread_type::thread_type;
scoped_thread()
: thread_type() {}
scoped_thread( scoped_thread && other )
: thread_type( std::move( other ) ) {}
scoped_thread & operator = ( scoped_thread && other )
{
thread_type & ref = *this;
ref = std::move( other );
return *this;
}
~scoped_thread()
{
if( thread_type::joinable() )
thread_type::join();
}
};
// handles autonomous threads safely
// Acts the same as the underlying thread type, except during destruction.
// If joinable, will call detach during destruction.
// Make sure it doesn't use any scoped resources since the thread can remain
// running after they go out of scope!
template <class UNDERLYING_THREAD = std::thread>
class free_thread
{
// same except it calls detach();
}
This seems to work, but I'm wondering if there is a way to avoid manually defining the constructors and the move assignment operator. Probably the biggest issue I noticed is that compilation will fail if you supply a class with deleted move constructor as a template argument.
Do you have any suggestions about how to possibly avoid this? Or are there other, bigger issues with this approach?
If you want proper exception handling with asynchronous tasks, maybe you should use std::future rather than std::thread. Instead of using join(), you'd use get() on the future, and if the future threw an exception, then get() will result in the same exception.
A simple example:
#include <future>
#include <iostream>
int my_future_task(int my_arg) {
throw std::runtime_error("BAD STUFF!");
return my_arg;
}
int main(int argc, char* argv[]) {
auto my_future = std::async(my_future_task, 42);
try {
my_future.get();
}
catch(std::exception &e) {
std::cout << "Caught exception: " << e.what() << std::endl;
}
return 0;
}
See also:
std::future::get
std::future_error
Exception propagation and std::future

Async constructor in C++11

Sometimes I need to create objects whose constructors take very long time to execute.
This leads to responsiveness problems in UI applications.
So I was wondering if it could be sensible to write a constructor designed to be called asynchronously, by passing a callback to it which will alert me when the object is available.
Below is a sample code:
class C
{
public:
// Standard ctor
C()
{
init();
}
// Designed for async ctor
C(std::function<void(void)> callback)
{
init();
callback();
}
private:
void init() // Should be replaced by delegating costructor (not yet supported by my compiler)
{
std::chrono::seconds s(2);
std::this_thread::sleep_for(s);
std::cout << "Object created" << std::endl;
}
};
int main(int argc, char* argv[])
{
auto msgQueue = std::queue<char>();
std::mutex m;
std::condition_variable cv;
auto notified = false;
// Some parallel task
auto f = []()
{
return 42;
};
// Callback to be called when the ctor ends
auto callback = [&m,&cv,&notified,&msgQueue]()
{
std::cout << "The object you were waiting for is now available" << std::endl;
// Notify that the ctor has ended
std::unique_lock<std::mutex> _(m);
msgQueue.push('x');
notified = true;
cv.notify_one();
};
// Start first task
auto ans = std::async(std::launch::async, f);
// Start second task (ctor)
std::async(std::launch::async, [&callback](){ auto c = C(callback); });
std::cout << "The answer is " << ans.get() << std::endl;
// Mimic typical UI message queue
auto done = false;
while(!done)
{
std::unique_lock<std::mutex> lock(m);
while(!notified)
{
cv.wait(lock);
}
while(!msgQueue.empty())
{
auto msg = msgQueue.front();
msgQueue.pop();
if(msg == 'x')
{
done = true;
}
}
}
std::cout << "Press a key to exit..." << std::endl;
getchar();
return 0;
}
Do you see any drawback in this design? Or do you know if there is a better approach?
EDIT
Following the hints of JoergB's answer, I tried to write a factory which will bear the responsibility to create an object in a sync or async way:
template <typename T, typename... Args>
class FutureFactory
{
public:
typedef std::unique_ptr<T> pT;
typedef std::future<pT> future_pT;
typedef std::function<void(pT)> callback_pT;
public:
static pT create_sync(Args... params)
{
return pT(new T(params...));
}
static future_pT create_async_byFuture(Args... params)
{
return std::async(std::launch::async, &FutureFactory<T, Args...>::create_sync, params...);
}
static void create_async_byCallback(callback_pT cb, Args... params)
{
std::async(std::launch::async, &FutureFactory<T, Args...>::manage_async_byCallback, cb, params...);
}
private:
FutureFactory(){}
static void manage_async_byCallback(callback_pT cb, Args... params)
{
auto ptr = FutureFactory<T, Args...>::create_sync(params...);
cb(std::move(ptr));
}
};
Your design seems very intrusive. I don't see a reason why the class would have to be aware of the callback.
Something like:
future<unique_ptr<C>> constructedObject = async(launchopt, [&callback]() {
unique_ptr<C> obj(new C());
callback();
return C;
})
or simply
future<unique_ptr<C>> constructedObject = async(launchopt, [&cv]() {
unique_ptr<C> ptr(new C());
cv.notify_all(); // or _one();
return ptr;
})
or just (without a future but a callback taking an argument):
async(launchopt, [&callback]() {
unique_ptr<C> ptr(new C());
callback(ptr);
})
should do just as well, shouldn't it? These also make sure that the callback is only ever called when a complete object is constructed (when deriving from C).
It shouldn't be too much effort to make any of these into a generic async_construct template.
Encapsulate your problem. Don't think about asynchronous constructors, just asynchronous methods which encapsulate your object creation.
It looks like you should be using std::future rather than constructing a message queue. std::future is a template class that holds a value and can retrieve the value blocking, timeout or polling:
std::future<int> fut = ans;
fut.wait();
auto result = fut.get();
I will suggest a hack using thread and signal handler.
1) Spawn a thread to do the task of the constructor. Lets call it child thread. This thread will intialise the values in your class.
2) After the constructor is completed, child thread uses the kill system call to send a signal to the parent thread. (Hint : SIGUSR1). The main thread on receiving the ASYNCHRONOUS handler call will know that the required object has been created.
Ofcourse, you can use fields like object-id to differentiate between multiple objects in creation.
My advice...
Think carefully about why you need to do such a long operation in a constructor.
I find often it is better to split the creation of an object into three parts
a) allocation
b) construction
c) initialization
For small objects it makes sense to do all three in one "new" operation. However, heavy weight objects, you really want to separate the stages. Figure out how much resource you need and allocate it. Construct the object in the memory into a valid, but empty state.
Then... do your long load operation into the already valid, but empty object.
I think I got this pattern a long time ago from reading a book (Scott Myers perhaps?) but I highly recommend it, it solves all sorts of problems. For example, if your object is a graphic object, you figure out how much memory it needs. If it fails, show the user an error as soon as possible. If not mark the object as not read yet. Then you can show it on screen, the user can also manipulate it, etc.
Initialize the object with an asynchronous file load, when it completes, set a flag in the object that says "loaded". When your update function sees it is loaded, it can draw the graphic.
It also REALLY helps with problems like construction order, where object A needs object B. You suddenly find you need to make A before B, oh no!! Simple, make an empty B, and pass it as a reference, as long as A is clever enough to know that be is empty, and wait to it is not before it uses it, all is well.
And... Not forgetting.. You can do the opposite on destruction.
Mark your object as empty first, so nothing new uses it (de-initialisation)
Free the resources, (destruction)
Then free the memory (deallocation)
The same benefits apply.
Having partially initialized objects could lead to bugs or unnecessarily complicated code, since you would have to check whether they're initialized or not.
I'd recommend using separate threads for UI and processing, and then use message queues for communicating between threads. Leave the UI thread for just handling the UI, which will then be more responsive all the time.
Place a message requesting creation of the object into the queue that the worker thread waits on, and then after the object has been created, the worker can put a message into UI queue indicating that the object is now ready.
Here's yet another pattern for consideration. It takes advantage of the fact that calling wait() on a future<> does not invalidate it. So, as long you never call get(), you're safe. This pattern's trade-off is that you incur the onerous overhead of calling wait() whenever a member function gets called.
class C
{
future<void> ready_;
public:
C()
{
ready_ = async([this]
{
this_thread::sleep_for(chrono::seconds(3));
cout << "I'm ready now." << endl;
});
}
// Every member function must start with ready_.wait(), even the destructor.
~C(){ ready_.wait(); }
void foo()
{
ready_.wait();
cout << __FUNCTION__ << endl;
}
};
int main()
{
C c;
c.foo();
return 0;
}

Checking if this is null

Does it ever make sense to check if this is null?
Say I have a class with a method; inside that method, I check this == NULL, and if it is, return an error code.
If this is null, then that means the object is deleted. Is the method even able to return anything?
Update: I forgot to mention that the method can be called from multiple threads and it may cause the object to be deleted while another thread is inside the method.
Does it ever make sense to check for this==null? I found this while doing a code review.
In standard C++, it does not, because any call on a null pointer is already undefined behavior, so any code relying on such checks is non-standard (there's no guarantee that the check will even be executed).
Note that this holds true for non-virtual functions as well.
Some implementations permit this==0, however, and consequently libraries written specifically for those implementations will sometimes use it as a hack. A good example of such a pair is VC++ and MFC - I don't recall the exact code, but I distinctly remember seeing if (this == NULL) checks in MFC source code somewhere.
It may also be there as a debugging aid, because at some point in the past this code was hit with this==0 because of a mistake in the caller, so a check was inserted to catch future instances of that. An assert would make more sense for such things, though.
If this == null then that means the object is deleted.
No, it doesn't mean that. It means that a method was called on a null pointer, or on a reference obtained from a null pointer (though obtaining such a reference is already U.B.). This has nothing to do with delete, and does not require any objects of this type to have ever existed.
Your note about threads is worrisome. I'm pretty sure you have a race condition that can lead to a crash. If a thread deletes an object and zeros the pointer, another thread could make a call through that pointer between those two operations, leading to this being non-null and also not valid, resulting in a crash. Similarly, if a thread calls a method while another thread is in the middle of creating the object, you may also get a crash.
Short answer, you really need to use a mutex or something to synchonize access to this variable. You need to ensure that this is never null or you're going to have problems.
I know that this is old but I feel like now that we're dealing with C++11-17 somebody should mention lambdas. If you capture this into a lambda that is going to be called asynchronously at a later point in time, it is possible that your "this" object gets destroyed before that lambda is invoked.
i.e passing it as a callback to some time-expensive function that is run from a separate thread or just asynchronously in general
EDIT: Just to be clear, the question was "Does it ever make sense to check if this is null" I am merely offering a scenario where it does make sense that might become more prevalent with the wider use of modern C++.
Contrived example:
This code is completely runable. To see unsafe behavior just comment out the call to safe behavior and uncomment the unsafe behavior call.
#include <memory>
#include <functional>
#include <iostream>
#include <future>
class SomeAPI
{
public:
SomeAPI() = default;
void DoWork(std::function<void(int)> cb)
{
DoAsync(cb);
}
private:
void DoAsync(std::function<void(int)> cb)
{
std::cout << "SomeAPI about to do async work\n";
m_future = std::async(std::launch::async, [](auto cb)
{
std::cout << "Async thread sleeping 10 seconds (Doing work).\n";
std::this_thread::sleep_for(std::chrono::seconds{ 10 });
// Do a bunch of work and set a status indicating success or failure.
// Assume 0 is success.
int status = 0;
std::cout << "Executing callback.\n";
cb(status);
std::cout << "Callback Executed.\n";
}, cb);
};
std::future<void> m_future;
};
class SomeOtherClass
{
public:
void SetSuccess(int success) { m_success = success; }
private:
bool m_success = false;
};
class SomeClass : public std::enable_shared_from_this<SomeClass>
{
public:
SomeClass(SomeAPI* api)
: m_api(api)
{
}
void DoWorkUnsafe()
{
std::cout << "DoWorkUnsafe about to pass callback to async executer.\n";
// Call DoWork on the API.
// DoWork takes some time.
// When DoWork is finished, it calls the callback that we sent in.
m_api->DoWork([this](int status)
{
// Undefined behavior
m_value = 17;
// Crash
m_data->SetSuccess(true);
ReportSuccess();
});
}
void DoWorkSafe()
{
// Create a weak point from a shared pointer to this.
std::weak_ptr<SomeClass> this_ = shared_from_this();
std::cout << "DoWorkSafe about to pass callback to async executer.\n";
// Capture the weak pointer.
m_api->DoWork([this_](int status)
{
// Test the weak pointer.
if (auto sp = this_.lock())
{
std::cout << "Async work finished.\n";
// If its good, then we are still alive and safe to execute on this.
sp->m_value = 17;
sp->m_data->SetSuccess(true);
sp->ReportSuccess();
}
});
}
private:
void ReportSuccess()
{
// Tell everyone who cares that a thing has succeeded.
};
SomeAPI* m_api;
std::shared_ptr<SomeOtherClass> m_data = std::shared_ptr<SomeOtherClass>();
int m_value;
};
int main()
{
std::shared_ptr<SomeAPI> api = std::make_shared<SomeAPI>();
std::shared_ptr<SomeClass> someClass = std::make_shared<SomeClass>(api.get());
someClass->DoWorkSafe();
// Comment out the above line and uncomment the below line
// to see the unsafe behavior.
//someClass->DoWorkUnsafe();
std::cout << "Deleting someClass\n";
someClass.reset();
std::cout << "Main thread sleeping for 20 seconds.\n";
std::this_thread::sleep_for(std::chrono::seconds{ 20 });
return 0;
}
FWIW, I have used debugging checks for (this != NULL) in assertions before which have helped catch defective code. Not that the code would have necessarily gotten too far with out a crash, but on small embedded systems that don't have memory protection, the assertions actually helped.
On systems with memory protection, the OS will generally hit an access violation if called with a NULL this pointer, so there's less value in asserting this != NULL. However, see Pavel's comment for why it's not necessarily worthless on even protected systems.
Your method will most likely (may vary between compilers) be able to run and also be able to return a value. As long as it does not access any instance variables. If it tries this it will crash.
As others pointed out you can not use this test to see if an object has been deleted. Even if you could, it would not work, because the object may be deleted by another thread just after the test but before you execute the next line after the test. Use Thread synchronization instead.
If this is null there is a bug in your program, most likely in the design of your program.
I'd also add that it's usually better to avoid null or NULL. I think the standard is changing yet again here but for now 0 is really what you want to check for to be absolutely sure you're getting what you want.
This is just a pointer passed as the first argument to a function (which is exactly what makes it a method). So long as you're not talking about virtual methods and/or virtual inheritance, then yes, you can find yourself executing an instance method, with a null instance. As others said, you almost certainly won't get very far with that execution before problems arise, but robust coding should probably check for that situation, with an assert. At least, it makes sense when you suspect it could be occuring for some reason, but need to track down exactly which class / call stack it's occurring in.
I know this is a old question, however I thought I will share my experience with use of Lambda capture
#include <iostream>
#include <memory>
using std::unique_ptr;
using std::make_unique;
using std::cout;
using std::endl;
class foo {
public:
foo(int no) : no_(no) {
}
template <typename Lambda>
void lambda_func(Lambda&& l) {
cout << "No is " << no_ << endl;
l();
}
private:
int no_;
};
int main() {
auto f = std::make_unique<foo>(10);
f->lambda_func([f = std::move(f)] () mutable {
cout << "lambda ==> " << endl;
cout << "lambda <== " << endl;
});
return 0;
}
This code segment faults
$ g++ -std=c++14 uniqueptr.cpp
$ ./a.out
Segmentation fault (core dumped)
If I remove the std::cout statement from lambda_func The code runs to completion.
It seems like, this statement f->lambda_func([f = std::move(f)] () mutable { processes lambda captures before member function is invoked.