LabWindows/CVI User Group Documents

cancel
Showing results for 
Search instead for 
Did you mean: 

LabWindows/CVI Tip: Debugging Memory Leaks in LabWindows/CVI Applications

Summary

Memory leaks are particularly problematic in C applications because they are hard to find, and debugging them can require time. Memory leaks are usually caused by accumulating unfreed memory pointers (e.g. malloc) or open resources (LoadPanel, CA_AllocMemory, etc.). Accumulation of unfreed pointers and open resources can especially cause problems for long-running applications by affecting performance or causing the application to crash, thus potentially losing any unsaved logged data.

Contents

  1. Preventing Memory Leaks
  2. Detecting Memory Leaks using LabWindows/CVI Resource Tracking

Preventing Memory Leaks

The best way to prevent memory leaks before they occur at run time is through several best practices:

  1. Defining and following a resource allocation/disposal policy consistent across your source code and development team. Choose a guideline for specifying the responsibility of how memory is allocated, and when anyone who uses that resource should free it.
  2. Particularly useful for LabWindows/CVI programs are the errChk and nullChk macros found in the Programmer’s Toolbox. Using the errChk/nullChk mechanism, you can implement a reliable management of the lifecycle of your resources at function level. The following code snippet shows an example of how you can easily ensure that the allocated resources are freed at the ending of the function: if the SetCtrlVal function returns an error, the errChk macro will jump execution to the Error label at the end of the function, ensuring resources are freed properly. Note that error checking will not guarantee the prevention of memory leaks if a consistent policy is not enforced in your source code.

    int InitializeMyUI (int panel, int ctrl) {
        int error = 0;
        char *string = (char *)malloc (BUFFER_SIZE);
        errChk (SetCtrlVal (panel, ctrl, “Hello, world!”));
        // Execute code that uses the “string” variable.
    Error:
        // Free allocated resources.
        free (string);
        return error;
    }

  3. Initialize pointers to NULL. It’s also a good practice to reset pointers to NULL immediately upon freeing them. Resetting the value of the pointer will indicate that the handle no longer points to a valid resource on subsequent uses of that variable.

  4. Don’t mix references to dynamically allocated memory with references to other types of memory like static allocated memory using the same pointer variable.

  5. When you are freeing compound structures containing various data (such as pointers to structs containing pointers to other resources), make sure your deallocation procedure also individually frees the resources pointed by your initial pointer. A typical example of this situation is a dynamically allocated array whose elements point to other resources:

    Context *DeviceContext = (Context *)malloc (sizeof (DeviceContext));
    // Code that uses the DeviceContext variable here.
    // Free allocated memory pointed by DeviceContext members.
    free (DeviceContext->portHandle);
    // Free the DeviceContext itself.
    free (DeviceContext);

Detecting Memory Leaks using LabWindows/CVI Resource Tracking

One of the first steps to perform when trying to debug memory leaks is simplifying your algorithm. Make sure you rule out the possibility of other code interfering with your debugging.

Secondly, a quick way to perform probing around certain function calls is to use the CVIDynamicMemoryInfo Utility Library function. The function returns information about the dynamic memory your application uses. It determines the total number of memory blocks allocated and the total number of bytes allocated. You can use the function to identify certain memory variation trends before and after function calls.

Consider using the LabWindows/CVI Resource Tracking window to intuitively detect memory leaks in your program. You must manually enable resource tracking when debugging an application under the Standard debugging level (select Options » Build Options » Debugging Options and explicitly call SetEnableResourceTracking). However, resource tracking is enabled by default in the Extended debugging level. Programmatically check whether resource tracking is enabled using the GetEnableResourceTracking function. Use resource tracking to record individual instances of allocated LabWindows/CVI resources such as files, loaded modules, threads, panels, ActiveX handles, or most commonly dynamic memory blocks. You can navigate to the source code location where a particular resource has been allocated by double-clicking its entry in the Resource Tracking window.

Resource Tracking Window.png

Refer to the related LabWindows/CVI Help topics for more details on using the Resource Tracking window.

Did you find this tip useful? Rate this document or add a comment below.

If you give this a try, share your experience! Add a comment below.

Comments
jbrown60
Member
Member
on

Just what I was looking for. Knew there was a way to do it, but forgot where it was. Thank you.

Contributors