0

what happens to data created in local scope of thread if thread is terminated, memory leak?

void MyThread()
{
    auto* ptr = new int[10];

    while (true)
    {
        // stuff
    }

    // thread is interrupted before this delete
    delete[] ptr;
}
  • 2
    How is the thread being terminated? – NathanOliver Sep 15 '21 at 15:30
  • More than likely, if the thread is interrupted before `delete` is called, there will be a memory leak. See https://stackoverflow.com/questions/51861511/dynamic-allocation-and-release-in-thread – h0r53 Sep 15 '21 at 15:31
  • injected dll, process terminate thread on exit but i want clean up i think i store glboal pointer now so it ok –  Sep 15 '21 at 15:31
  • 4
    @user16850544 when you say `process terminate thread on exit` are you suggesting the entire process exits, and not just the thread? If so, then you don't really have an issue. The concept of memory leaks only applies to a running process. On exit all of the process address space is "cleaned" – h0r53 Sep 15 '21 at 15:33
  • @h0r53 ok thank u i just want make sure it all good –  Sep 15 '21 at 15:34
  • @user16850544 Beware of C++'s progress guarantee. It means that certain `while(true) { /* ... */ }` loops are Undefined Behavior and can be simply completely removed by the compiler during optimization. See [progress guarantee](https://en.cppreference.com/w/cpp/language/memory_model#Progress_guarantee) and [Optimizing away a "while(1);" in C++0x](https://stackoverflow.com/questions/3592557/optimizing-away-a-while1-in-c0x). – François Andrieux Sep 15 '21 at 15:38
  • @user16850544 if it's on process exit then don't try to do anything. Just let it die. At that point it's like trying to close the drapes in a burning house. The best you can do is handle things when your DLL is unloaded. But if you're injecting code don't be surprised when the host process doesn't play nice. Regardless there is no impact because all the memory is reclaimed by the kernel on process exit anyway – Mgetz Sep 15 '21 at 15:44
  • 3
    BTW: use RAII pattern. In this case `std::vector` (or `auto ptr = std::make_unique(10);`). – Marek R Sep 15 '21 at 15:56
  • @FrançoisAndrieux I think we are meant to assume that the `stuff` comment stands for some code that would include a `break` statement at some point, otherwise the `delete[] ptr` line could never be reached. – Jeremy Friesner Sep 16 '21 at 00:22

1 Answers1

0

Okay, my perspective.

If the program exits, the threads exit wherever they are. They don't clean up. But in this case you don't care. You might care if it's an open file and you want it flushed.

However, I prefer a way to tell my threads to exit cleanly. This isn't perfect, but instead of while (true) you can do while (iSHouldRun) and set the field to false when it's time for the thread to exit.

You can also set a flag that says, iAmExiting at the end, then myThread.join() once the flag is set. That gives your exit code a chance to clean up nicely.

Coding this from the beginning helps when you write your unit tests.

The other thing -- as someone mentioned in comments -- use RAII. Pretty much if you're using raw pointers, you're doing something you shouldn't do in modern C++.

That's not an absolute. You can write your own RAII classes. For instance:

class MyIntArray {
    MyArray(int sizeIn) { ... }
    ~MyArray() { delete array; }

private:
    int * array = nullptr;
    int size = 0;
};

You'll need a few more methods to actually get to the data, like an operator[]. Now, this isn't any different than using std::vector, so it's only an example of how to implement RAII for your custom data, for instance.

But your functions should NEVER call new like this. It's old-school. If your method pukes somehow, you have a memory leak. If it pukes on exit(), no one cares. But if it pukes for another reason, it's a problem. RAII is a much, much better solution than the other patterns.

Joseph Larson
  • 8,530
  • 1
  • 19
  • 36
  • Note that if the thread is unilaterally terminated (e.g. via a call to the Win32 `TerminateThread()` function, or similar) then even RAII won't save you from a resouce leak, because RAII depends on destructors executing and killing a thread prevents it from ever running its destructors. (which leads to the conclusion that it's never safe to unilaterally kill a thread; rather you should always ask it politely to go away and then wait for it to do so, as described in this answer) – Jeremy Friesner Sep 16 '21 at 00:27
  • @JeremyFriesner Yes, which is why I recommend a different way to terminate threads -- asking them to exit instead of forcing them. See paragraph 3 of my answer. – Joseph Larson Sep 16 '21 at 18:51
  • we are in agreement; I was just trying to clarify for the OP. – Jeremy Friesner Sep 16 '21 at 18:53