The MS leak detector only runs because code in juce_core invokes it on shutdown. Not seeing the message when you don't use juce_core doesn't mean there isn't a leak, it just means its not being checked at all.
It's most likely just a win32 message left on the queue at exit, or a static variable somewhere that's not being deleted before the leak detector runs (which can happen before all other statics are destroyed).
(And come on, please.. even in test code there's no excuse to ever write 'delete', especially when you're explicitly using C++11 classes! Let's make this forum a place where we ALL try to set a good example to anyone reading it!)
void theThread()
{
// wait one second
std::unique_lock<std::mutex> lock(mutex);
conditionVariable.wait_for(lock, std::chrono::seconds(1));
finished = true;
}
int __stdcall WinMain (struct HINSTANCE__*, struct HINSTANCE__*, char*, int)
{
std::thread thread(theThread);
while (finished.load() == false)
std::this_thread::yield();
thread.join();
_CrtCheckMemory();
return 0;
}
And I added a call to _CrtCheckMemory() to check for leaks.
There is something strange.
Log without linking juce_core.cpp
'JuceDemo.exe' (Win32): Loaded 'C:\Windows\SysWOW64\advapi32.dll'. Cannot find or open the PDB file.
The thread 0x12b4 has exited with code 0 (0x0).
The thread 0x1594 has exited with code 0 (0x0).
The program '[0x1138] JuceDemo.exe' has exited with code 0 (0x0).
vs
Log linking juce_core.cpp
'JuceDemo.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msctf.dll'. Cannot find or open the PDB file.
The thread 0x4b4 has exited with code 0 (0x0).
Detected memory leaks!
Dumping objects ->
{204} normal block at 0x00BDAF00, 44 bytes long.
Data: < > 01 00 00 00 00 00 00 00 00 00 00 00 0A 00 00 00
Object dump complete.
The thread 0x119c has exited with code 0 (0x0).
The program '[0x64] JuceDemo.exe' has exited with code 0 (0x0).
Yes. Like I said, it'll be a static object somewhere.
Obviously if you run the leak checker in your main function - i.e. before the program's static destructors have been called - then that's exactly what you'd expect to see.
Adding a breakpoint in _nh_malloc_dbg_impl I found where the leak comes from:
int _Mtx_init(_Mtx_t *mtx, int type)
{ /* initialize mutex */
_Mtx_t mutex;
*mtx = 0;
if ((mutex = (mtx_t)calloc(1, sizeof (struct _Mtx_internal_imp_t))) == 0)
with stack
JuceDemo.exe!calloc(unsigned int nNum, unsigned int nSize) Line 56 C++
JuceDemo.exe!_Mtx_init(_Mtx_internal_imp_t * * mtx, int type) Line 24 C++
JuceDemo.exe!init_at_thread_exit_mutex() Line 28 C
JuceDemo.exe!_Call_once(char * cntrl, void (void) * func) Line 41 C
JuceDemo.exe!_Cnd_do_broadcast_at_thread_exit() Line 107 C
JuceDemo.exe!_Call_func(void * _Data) Line 70 C++
JuceDemo.exe!_callthreadstartex() Line 354 C
JuceDemo.exe!_threadstartex(void * ptd) Line 337 C
but I haven't found yet how this block gets freed when not linking with Juce. I'll keep investigating.
Another strange thing I found out is that the same code with Juce v3.1.1 generates a 72 byte leak, while with the current Juce v3.2.0 the leak size is 44 bytes...
To remove the annoying memory leak log when using std::thread together with Juce, try adding the following line at the beginning of main:
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
The documentation states that using this flag performs automatic leak checking at program exit. In this case it also prevents the false leak detection.