I'll go ahead and admit it now: When I first started looking into mixing managed and unmanaged code, I was a little skeptical. I wasn't certain that the unmanaged class I created was really unmanaged, and the CLR didn't have anything to do with it. So, I created a little test, which you will now do. As mentioned at the beginning of this hour, memory leaks are a result of allocating memory and then not releasing that memory once your application exits. The C-Runtime library contains a mechanism that allows you to detect any memory leaks within your application and also shows you where these leaks occur. The method to do this is quite simple and should be employed as much as possible. To enable memory leak detection in an application, you must first define a preprocessor definition named _CRTDBG_MAP_ALLOC and include the header file crtdbg.h. Place the following code near the top of the PInvoke.cpp file:
// enable memory leak detection #define _CRTDBG_MAP_ALLOC #include <crtdbg.h>
The next step is to tell the C runtime to dump any memory leaks. This is done by placing a call to _CrtDumpMemoryLeaks at any exit points within your application. Because this is a simple application, there is only one exit point at the end of the _tmain function. Before you run your application, however, you need to create a memory leak. The only place this can happen is with the CSystemTime object you created within the _tmain function. All other variables that you use are managed and therefore subject to garbage collection. To create the memory leak, comment out the line that deletes the pSysTime object within _tmain.
In order to see the output that contains memory leak information, you must run your application in debug mode. After compiling your application, click Debug, Start from the main menu. After your application has finished running, the memory leak information, as well as other debug statements issued by the WIN32 API, is contained within the Output window in the Visual Studio .NET IDE. Open the Output window if it isn't visible and scroll up a few lines. If everything has worked correctly, you will see a line that reads "Memory Leaks Detected," as shown in Figure 22.2. If you then uncomment the line and make sure the CSystemTime object is being deleted, you will see that once you run the application in debug mode, the memory leak is removed. This demonstrates that when you mix unmanaged code within a managed application, you are responsible for freeing any unmanaged objects before your application exits.