﻿# Memory leak

A memory leak is an error in the source code, when the dynamic memory allocated for a variable, array, class object, etc\. is not freed and is subsequently lost, while the data persist in RAM until the program is closed\. 

Such errors can overload the computer and slow down the performance while the application is running\. Moreover, such an application may consume memory endlessly\. Because of that, the OS eventually may terminate the problematic application and all of the application's processes\.

In some cases, such errors may be considered potential vulnerabilities for application\-level [DoS attacks](https://pvs-studio.com/en/blog/terms/6585/) in some cases\. This attack exhausts the system's resource limits\.

## Causes of memory leaks

When an application starts, some memory is allocated for the application's process and operations\. For each executed thread data structure called the stack is created\. Here the program stores information about variables, function calls, and other processes and releases these data instances one by one, only in reverse order\.

However, the stack size is limited and the program may request more memory that has not yet been allocated by the OS\. This type of dynamic memory is called the heap\.

To work with data on the heap, the program uses pointers\. These are special variables that contain a RAM block's address\. But unlike the stack, the heap does not automatically release memory after the data processing is complete\. Therefore, the developer has to free memory manually\. Moreover, if the pointer referring to the allocated memory fragment is lost, this memory cannot be released\.

In C\+\+ code, dynamic memory is allocated by the [_operator new_](https://en.cppreference.com/w/cpp/memory/new/operator_new)\. In C code, dynamic memory is allocated by the following functions: [_malloc_](https://en.cppreference.com/w/c/memory/malloc), [_realloc_](https://en.cppreference.com/w/c/memory/realloc), [_calloc_](https://en.cppreference.com/w/c/memory/calloc), [_strdup_](https://en.cppreference.com/w/c/experimental/dynamic/strdup), etc\. The developer can release a memory block with the [_operator delete_](https://en.cppreference.com/w/cpp/memory/new/operator_delete)_ _\(C\+\+\) or the [_free_](https://en.cppreference.com/w/c/memory/free) function \(C\)\.



In large projects, functions, structures, classes constantly exchange pointers\. As a result, it becomes difficult to track when memory is allocated and freed\. This is what provokes memory leak errors\.

Let's look at a memory leak that the PVS\-Studio analyzer detected in the Augeas project:

```cpp
static void xfm_error(struct tree *xfm, const char *msg) {
  char *v = msg ? strdup(msg) : NULL;
  char *l = strdup("error");

  if (l == NULL || v == NULL)
    return;
  tree_append(xfm, l, v);
}
```

Though the function is short, it can lead to three memory leak scenarios\. Two scenarios are unlikely, but the third one is probable\.

Let's discuss the first two scenarios\. One of the _strdup_ function calls returns _NULL_\. In this case, the function returns early and the pointer returned by the other _strdup_ call is lost\. These scenarios seem unlikely, but they are still possible\.

The third one is more probable\. The _xfm\_error_ function expects that the value of the _msg_ argument can be _NULL_\. In this case the function returns early\. However, the memory allocated by the _strdup\("error"\)_ call will be lost\.

To avoid all these errors, you can rewrite the code as follows:

```cpp
static void xfm_error(struct tree *xfm, const char *msg) {
  if (msg == NULL)
    return;
  char *v = strdup(msg);
  if (v == NULL)
    return;
  char *l = strdup("error");
  if (l == NULL) {
    free(v);
  }
  tree_append(xfm, l, v);
}
```

Unfortunately, there is more code now, and the code became cumbersome and more susceptible to errors\. This is why C developers often run into errors when they manage memory\.

Note\. We recommend you to also read a similar article: "[Four reasons to check what the malloc function returned](https://pvs-studio.com/en/blog/posts/cpp/0938/)"\.

## Consequences of memory leaks

If you leave data in dynamic memory uncleared, RAM may run out\. At this point the OS will automatically terminate the process of our program and won't save the past work\. If your OS does not accommodate for this emergency shutdown \(e\.g\. some Linux distributions require to download a special utility\), the computer may freeze or slow down significantly\. As a result, you would have to wait for the program's, and consequently, the computer's response to close the program properly\. Sometimes the system may slow down so much that all you would be able to do is to restart the computer\.

It gets much worse when other applications are integrated into the program\. In this case, all related processes are terminated, including those that you've been running for your own needs\. 

Moreover, because of memory leaks, you may lose data that the application was using and that you were using in a related app and did not save\. For example, if RAM runs out while the application was running editors and other third\-party tools in the background\.

## How to avoid memory leaks

C and C\+\+ developers manage memory manually, unlike C\# and Java developers – the garbage collector manages the heap for them\. However, the C\+\+ language has a protection mechanism against memory leaks\. It is implemented with "smart" pointers, such as [_std::unique\_ptr_](https://en.cppreference.com/w/cpp/memory/unique_ptr), [_std::shared\_ptr_](https://en.cppreference.com/w/cpp/memory/shared_ptr), etc\.

To ensure that there are no leaks in a program, developers use dynamic analysis tools to look for bugs\. In Visual Studio you can use the [Debug CRT](https://docs.microsoft.com/en-us/visualstudio/debugger/crt-debug-library-use?view=vs-2022) library\. The _\_CrtDumpMemoryLeaks_ function is called at the program completion point\. When debugging stops, you can find the leak report in the Output window's Debug pane\. This library checks for any memory allocation via _new_ or the _malloc_ function\.

You can use third\-party tools that integrate into the Visual Studio environment\. Visual Leak Detector is a program, that informs users about all files and code lines where leaks occurred\. You can also find this program in the same Output window\.

On Unix\-like operating systems \(Linux, macOS\) you can use [_Leak Sanitizer_](https://clang.llvm.org/docs/LeakSanitizer.html)\. Starting with 2019, it's been also available on Windows\. This tool can be used as part of the more advanced [_Address Sanitizer_](https://clang.llvm.org/docs/AddressSanitizer.html) or – in standalone mode\. Compile your program with the _\-fsanitize\=leak_ flag to use Leak Sanitizer in standalone mode\. Alternatively, indicate the _\-fsanitize\=address_ flag to use _Address Sanitizer_\. When this tool detects a memory leak, it logs the information about the leak to the standard error output stream\.

The PVS\-Studio static analyzer [can](https://pvs-studio.com/en/blog/posts/cpp/0543/) also [detect](https://pvs-studio.com/en/blog/posts/cpp/0543/) many types of memory leaks\. However, static code analysis is not as accurate, as dynamic code analysis\. Static analyzers check the entire program code and can detect leaks even in rarely\-used code\. Dynamic analyzers fail to cover the entire program code\. 

In cases when a leak cannot be fixed — for example, in a third\-party library that does not allow access to its source code – developers can write a bug report to the library's authors, attempt to update the library or look for similar third\-party libraries\. If you need an exact library, you can use a separate process to execute functions that use this library\. This way, memory leaks will still be formed, but you can control them by running and ending the process when needed\.

**Additional resources:**

1. Wikipedia, [Memory leak](https://en.wikipedia.org/wiki/Memory_leak)\.
1. Standard C\+\+ Foundation\. [Memory Management](https://isocpp.org/wiki/faq/freestore-mgmt)\.
1. [Memory Management Lecture \- Breda University of applied sciences \- Games](https://gist.github.com/simonrenger/d1da2a10d11f8a971fc6f1b574ab3e99)\.
1. [How to detect errors and bugs in code? Explaining Memory Leaks in C\+\+](https://youtu.be/AeyTSLGIX1M)\.
1. [Yes, PVS\-Studio Can Detect Memory Leaks](https://pvs-studio.com/en/blog/posts/cpp/0543/)\.