Описание
Освобождение ранее освобожденного указателя происходит, когда блок памяти освобожден несколько раз с помощью функции free
без промежуточного выделения.
Риск
Когда указатель является выделенной динамической памятью с malloc
, calloc
или realloc
, это указывает на ячейку памяти на куче. Когда вы используете функцию free
на этом указателе, связанный блок памяти освобожден для перераспределения. Попытка освободить этот блок от памяти может привести к отказу сегментации.
Фиксация
Фиксация зависит от первопричины дефекта. Смотрите, намеревались ли вы выделить блок памяти указателю между первым освобождением и вторым. В противном случае удалите второй оператор free
.
Как хорошая практика, после того, как вы освободите блок памяти, присваивают соответствующий указатель на NULL. Прежде, чем освободить указатели, проверяйте их на Нулевые значения и обработайте ошибку. Таким образом вы защищены от освобождения уже освобожденного блока.
Пример - освобождение ранее освобожденной ошибки указателя
#include <stdlib.h>
void allocate_and_free(void)
{
int* pi = (int*)malloc(sizeof(int));
if (pi == NULL) return;
*pi = 2;
free(pi);
free (pi);
/* Defect: pi has already been freed */
}
Первый оператор free
выпускает блок памяти, к которой относится pi
. Второй оператор free
на pi
выпускает блок памяти, которая уже была освобождена.
Исправление — удаляет дублирующееся освобождение
Одно возможное исправление должно удалить второй оператор free
.
#include <stdlib.h>
void allocate_and_free(void)
{
int* pi = (int*)malloc(sizeof(int));
if (pi == NULL) return;
*pi = 2;
free(pi);
/* Fix: remove second deallocation */
}