ПроблемаУтечка памяти происходит, когда вы не освобождаете блок от памяти, выделенной через 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);
} См.
правило MEM00-C CERT-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 функция. 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;
}