Click here to Skip to main content
13,254,366 members (57,159 online)
Click here to Skip to main content
Add your own
alternative version

Stats

6.2K views
44 downloads
8 bookmarked
Posted 30 Apr 2017

Allocating Memory in C/C++: How to Avoid Memory Mismatched Allocation/Deallocation Issues Detected by Intel® Inspector XE for Visual Studio 2015

, 1 May 2017
Rate this:
Please Sign up or sign in to vote.
This tip/trick introduces the basic ideas on how to avoid memory mismatched allocation/deallocation issues detected by Intel® Inspector XE for Visual Studio 2015

Introduction

While using Intel® Inspector XE in Visual Studio 2015 to detect memory leaks and stack manipulation issues in your code written in C/C++, you’ve might encountered that Intel® Inspector XE detects mismatched allocation/deallocation issues even though you properly deallocate each buffer after it has been previously allocated. In this article, we’ll discuss about how to properly deallocate memory buffers being allocated to survive memory mismatched allocation/deallocation issues detected by Intel® Inspector XE.

Memory Mismatched Allocation/Deallocation Issues

Suppose you have the following code that allocates a buffer in memory to store an array of N objects of specific type DATA and assigns address of buffer in memory to the pointer variable data:

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

typedef struct tagData
{
 char* string;
} DATA, NEAR *PDATA, FAR* LPDATA;

const size_t N = 10;

int main()
{
 int count = 10;
 while (--count >= 0)
 {
  LPDATA data = (LPDATA)malloc(sizeof(DATA) * N);
  memset((void*)&data[0], 0x00, sizeof(DATA) * N);

  const size_t length = 1024;
  for (size_t index = 0; index < N; index++)
  {
   data[index].string = (char*)malloc(length);
   sprintf(data[index].string, "string: %zu", index);
  }

  // Do some work at here

  for (size_t index = 0; index < N; index++)
   free(data[index].string);

  free(data);
 }

    return 0;
}

This is typically done by calling one of those C memory allocation functions such as calloc, malloc, realloc, as well as using new[] and delete[] operators in C++. Then, we’re iterating through the array of objects data and for each object we’re allocating process memory to store a character buffer string of size length using those memory allocation functions. In this case, we’re iteratively assigning the address of buffer being allocated to the pointer variable string of each particular object data[index].

Since those memory buffers have been allocated, we can do some work using the buffers being allocated. Finally, according to the best programming practices, to avoid memory leaks, we need to smartly deallocate specific buffers at the end of the code execution. To do this, we iterate through the array of objects, and for each particular object we deallocate memory used to store a string buffer by using C function free(data[index].string) or delete[] data[index].string operator in C++. After that, we deallocate buffer used to store an array of objects data using the same free(data) function.

Normally, by executing the following code listed above, we will see that it obviously can be successfully executed providing the correct results with no memory leaks or other issues at the end of its execution. However, by using Intel® Inspector XE to detect and analyze memory leaks or other issues that might persist during the code execution, we might encounter that the following code suddenly incurs a series of mismatched allocation/deallocation problems. We purposely repeat the process of memory allocation/deallocation to create workload on the CPU so that the following problems are easily detected by Intel® Inspector XE. Those problems basically occur when running the following code under Windows kernel:

The main reason why those problems might be incurred by this code and thus detected by the Intel® Inspector XE is that calling the either free(data[index].string) function or free(data) does not actually deallocate the buffers when the following code is run under Windows kernel. Calling of these functions is equivalent to assigning the null-pointer to the specific pointer variables such as (data = nullptr). In turn, the memory being previously allocated at the beginning of code execution is automatically redistributed by the Windows kernel among other running processes. That’s actually why, Intel® Inspector suddenly detects those issues being discussed in this article.

Workaround

As a workaround to the problem being discussed, we have to use ::VirtualAllocEx(...) and ::VirtualFreeEx(...) WinAPI-functions to properly allocate/deallocate memory buffers. Also, to make sure, that we’re actually deallocating memory that was previously allocated, we have to perform a check if the value of address assigned to a pointer variable is not equal to nullptr. If so, perform deallocation, otherwise do nothing. Memory buffers allocation/deallocation is typically done as shown in the code example below:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <memory.h>

#include <Windows.h>

typedef struct tagData
{
 char* string;
} DATA, NEAR *PDATA, FAR* LPDATA;

const size_t N = 10;

int main()
{
 int count = 10;
 while (--count >= 0)
 {
  HANDLE hProcHandle = ::GetCurrentProcess();

  LPDATA data = (LPDATA)::VirtualAllocEx(hProcHandle, NULL, \
   sizeof(DATA) * N, MEM_COMMIT, PAGE_READWRITE);
  ::ZeroMemory((void*)&data[0], sizeof(DATA) * N);

  const size_t length = 1024;
  for (size_t index = 0; index < N; index++)
  {
   data[index].string = (char*)::VirtualAllocEx(hProcHandle, NULL, \
    length, MEM_COMMIT, PAGE_READWRITE);
   sprintf(data[index].string, "string: %zu", index);
  }

  // Do some work here

  for (size_t index = 0; index < N; index++)
   if (data[index].string != NULL)
    ::VirtualFreeEx(hProcHandle, data[index].string, length, MEM_RELEASE);

  if (data != NULL)
   ::VirtualFreeEx(hProcHandle, data, sizeof(DATA) * N, MEM_RELEASE);
 }

    return 0;
}

In this case, unlike using malloc(…) and free(…) functions, ::VirtualAllocEx(...) and ::VirtualFreeEx(…) WinAPI - functions allocate/deallocate specific buffers in Windows kernel virtual memory address space. Since that, Intel® Inspector XE no longer detects any problems such as the memory allocation/deallocation mismatch. The detailed description of those functions that perform virtual memory management can be found here.

History

  • May 1, 2017 - The first revision of this tip/trick was published

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Arthur V. Ratz
Software Developer (Senior) Engineer DPLKB
Ukraine Ukraine
Arthur V. Ratz, 35 years old, C++ software developer, system analyst and network engineer graduated from L’viv State Polytechnical University (L'viv, Ukraine) and attained his Computer science and Information technology master’s degree in January 2004. Since the middle of 2005, Arthur Ratz is a senior IT-professional. His professional career began as a financial and accounting software developer in DPLKB company’s small local branch in L’viv, Ukraine. His professional interests include C/C++ programming, windows platform applications development using Win32API, parallel programming and multithreading, SQL relational database development, PHP and JavaScript web development, algorithms, system analysis, distributed information systems, computers networks design and analyzing, Windows Server and Linux administration, cloud computing, IoT, system security, technical writing and science publications etc. Arthur Ratz published his first article at CodeProject.com in June 2015.

You may also be interested in...

Pro
Pro

Comments and Discussions

 
GeneralMy vote of 5 Pin
eslipak1-May-17 9:24
professionaleslipak1-May-17 9:24 
QuestionC++ Memory Allocation/Deallocation and Thread Safety Pin
Jon Summers1-May-17 4:03
memberJon Summers1-May-17 4:03 
AnswerRe: C++ Memory Allocation/Deallocation and Thread Safety Pin
Arthur V. Ratz1-May-17 4:37
professionalArthur V. Ratz1-May-17 4:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171114.1 | Last Updated 1 May 2017
Article Copyright 2017 by Arthur V. Ratz
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid