2

Below are the example we used.

class CustomThread
{
public:
    CustomThread(const std::wstring &id1)
    {
         t = new test(id1);
    }
    ~CustomThread();        

    void startThread() {
        std::cout << "Do threading Operation here....." << std::endl;
    }

private:
    std::wstring id;
    test *t;
};


int main()
{
    for (int i = 1; i < 100; i++)
    {
        std::wstring id = L"1";
        CustomThread *ct = new CustomThread(id);

        boost::thread new_thread;
        new_thread = boost::thread(& CustomThread::startThread, ct);
        new_thread.detach();        
    }

    // sleep for 100 second - to complete the thread task....
    sleep(100);
    return 0;

}

I created detachable thread and I want to start 100 detachable thread. Here we are doing new CustomThread 100 times and allocating memory. Is it automatically deleted once the thread finish the operation? Can you guide how to free the allocated memory with above example?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Neel
  • 451
  • 1
  • 9
  • 23
  • 2
    If you call `new` you **must** call `delete`. That is the rule. – NathanOliver Aug 28 '17 at 11:55
  • That is true. But here we don't know when detachable thread finish its operation. so when should we call delete ? – Neel Aug 28 '17 at 11:56
  • 2
    The trick to memory management in C++ is to never use `new`. – nwp Aug 28 '17 at 11:57
  • Not only are you loosing your "test" variable, but also the CustomThread instance.... – Hafnernuss Aug 28 '17 at 11:57
  • 3
    Any particular reason you use pointers all over the place? Prefer value semantics if you can. Even if your class is not copyable, it may still be moveable. – StoryTeller - Unslander Monica Aug 28 '17 at 11:59
  • If you detach your threads, you _have_ to cleanup at the end of the startThread method. And you should hold pointers to your CustomThreads in a vector or something to delete them. sleep(100) is pointless if you detached your threads, it would be better to join on them if you want to wait for them to finish... sleep in this case is unsecure (no guarantee the threads are finished) and defeats the purpose of detach() – Hafnernuss Aug 28 '17 at 11:59
  • @Hafnernuss. Can we delete CustomThread in "startThread" method ? – Neel Aug 28 '17 at 12:08
  • well.... thats almost always a very bad idea... – Hafnernuss Aug 28 '17 at 12:15
  • 1
    Don't detach the threads. Instead of guessing how long they'll take to complete (that's the call to `sleep(100)`), join them. – Pete Becker Aug 28 '17 at 12:16
  • 1
    Question is why you need to create 100 threads and detach all of them. Maybe that's not the best design. – Dan Mašek Aug 28 '17 at 12:25
  • using a threadpool might also be a good idea. spawning 100 threads on a machine that can only process 8 at a time will create unnecessary overhead – Hafnernuss Aug 28 '17 at 12:30

1 Answers1

2

There are a couple issues here. First, since CustomThread acquires a resource it needs to follow the rule of three.

Now, lets look at your design. You dynamical allocate a CustomThread so that it won't be destroyed at then end of the for loop and will last for the lifetime of the thread. The problem here is you don't know exactly when to delete the class and even if you did you still don't have the pointer in order to call delete on it. You could store those pointers but you still run the risk of maybe deleting the object before the thread finishes. What we need to do is somehow couple the thread and object together in a way where we know the object is destroyed after the thread finishes running. We can do this with a helper function. If we have

void thread_runner(std::wstring param)
{
    CustomThread ct(param);
    ct.startThread();
}

Then we can call this function instead in the loop like

for (int i = 1; i < 100; i++)
{
    std::wstring id = L"1"; 
    boost::thread new_thread;
    new_thread = boost::thread(&thread_runner, id);
    new_thread.detach();        
}

Now the CustomThread object is cleaned up automatically and you don't have to worry about where and when to call delete (assuming your class has a proper destructor or you switch to a RAII pointer type).

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • and "test" should be destroyed in the destructor of CustomThread or at the and of the startThread method. – Hafnernuss Aug 28 '17 at 12:16
  • The purpose of the destructor is to free up resources the object may have acquired. Thus, it is generally the appropriate place to put your deletes. Given the code examples to so far, the destructor is definately where I'd put my delete of test. new it in the constructor, delete it in the destructor. – Darinth Aug 28 '17 at 12:57