Memory leak

Память, выделяемая динамически, не освобождается

Описание

Этот дефект возникает, когда вы не освобождаете блок памяти, выделенный через malloc, calloc, realloc, или new. Если память выделена в функции, дефект не возникает, если:

  • В рамках функции вы освобождаете память, используя free или delete.

  • Функция возвращает указатель, назначенный malloc, calloc, realloc, или new.

  • Функция сохраняет указатель в глобальной переменной или в параметре.

Риск

Динамические функции выделения памяти, такие как malloc выделите память на куче. Если вы не освобождаете память после использования, вы уменьшаете объем памяти, доступный для другого выделения. В встраиваемых системах с ограниченной памятью вы можете в конечном итоге исчерпать доступную память в куче даже во время выполнения программы.

Зафиксировать

Определите возможности, в которой осуществляется доступ к динамически выделенной памяти. Освободите блок памяти в конце этих возможностей.

Чтобы освободить блок памяти, используйте free функция на указателе, который использовался во время выделения памяти. Для образца:

ptr = (int*)malloc(sizeof(int));
...
free(ptr);

Это хорошая практика - выделять и освобождать память в том же модуле на том же уровне абстракции. Например, в этом примере func выделяет и освобождает память на том же уровне, но func2 не делает.

void func() {
  ptr = (int*)malloc(sizeof(int));
  {
    ...
  }
  free(ptr);
}

void func2() {
  {
   ptr = (int*)malloc(sizeof(int));
   ...
  }
  free(ptr);
}
См. Раздел «Правила CERT-C MEM00-C».

Примеры

расширить все

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

void assign_memory(void)
{
    int* pi = (int*)malloc(sizeof(int));
    if (pi == NULL) 
        {
         printf("Memory allocation failed");
         return;
        }


    *pi = 42;
    /* Defect: pi is not freed */
}

В этом примере pi динамически распределяется по malloc. Функция assign_memory не освобождает память и не возвращается pi.

Коррекция - бесплатная память

Одной из возможных коррекций является освобождение памяти, на которую ссылаются pi использование free функция. The free функция должна быть вызвана перед функцией assign_memory заканчивается

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

void assign_memory(void)
{
    int* pi = (int*)malloc(sizeof(int));
    if (pi == NULL) 
        {
         printf("Memory allocation failed");
         return;
        }
    *pi = 42;

    /* Fix: Free the pointer pi*/
    free(pi);                   
}
Коррекция - Возвращаемый указатель из динамического распределения

Еще одна возможная коррекция - вернуть указатель мыши pi. Возврат pi позволяет выполнять вызов функции assign_memory чтобы освободить блок памяти с помощью pi.

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

int* assign_memory(void)
{
    int* pi = (int*)malloc(sizeof(int));
    if (pi == NULL) 
        {
            printf("Memory allocation failed");
            return(pi);
        }
    *pi = 42;

    /* Fix: Return the pointer pi*/
    return(pi);                   
}
#define NULL '\0'

void initialize_arr1(void)
{
    int *p_scalar = new int(5);
}

void initialize_arr2(void)
{
    int *p_array = new int[5];
}

В этом примере функции создают две переменные, p_scalar и p_array, с использованием new ключевое слово. Однако функции заканчиваются без очистки памяти для этих указателей. Потому что используемые функции new чтобы создать эти переменные, необходимо очистить их память путем вызова delete в конце каждой функции.

Коррекция - Добавить Удалить

Чтобы исправить эту ошибку, добавьте delete оператор для каждого new инициализация. Если вы использовали скобки [] чтобы создать экземпляр переменной, необходимо также вызвать удаление с помощью скобок.

#define NULL '\0'

void initialize_arrs(void)
{
    int *p_scalar = new int(5); 
    int *p_array = new int[5];  

    delete p_scalar;
    p_scalar = NULL;

    delete[] p_array;
    p_scalar = NULL;
}

Информация о результатах

Группа: Динамическая память
Язык: C | C++
По умолчанию: Off
Синтаксис командной строки: MEM_LEAK
Влияние: Средний
ИДЕНТИФИКАТОР CWE: 401, 404
Введенный в R2013b