ПроблемаИспользование ранее освобожденного указателя происходит, когда вы получаете доступ к блоку памяти после освобождения блока с помощью free
функция.
РискКогда указатель является выделенной динамической памятью с malloc
, calloc
или realloc
, это указывает на ячейку памяти на куче. Когда вы используете free
функция на этом указателе, связанный блок памяти освобожден для перераспределения. Попытка получить доступ к этому блоку памяти может привести к непредсказуемому поведению или даже отказу сегментации.
ИсправлениеФиксация зависит от первопричины дефекта. Смотрите, намеревались ли вы освободить память позже или выделить другой блок памяти указателю перед доступом.
Как хорошая практика, после того, как вы освободите блок памяти, присваивают соответствующий указатель на NULL. Прежде, чем разыменовать указатели, проверяйте их на Нулевые значения и обработайте ошибку. Таким образом вы защищены от доступа к освобожденному блоку.
Пример - использование ранее освобожденной ошибки указателя#include <stdlib.h>
#include <stdio.h>
int increment_content_of_address(int base_val, int shift)
{
int j;
int* pi = (int*)malloc(sizeof(int));
if (pi == NULL) return 0;
*pi = base_val;
free(pi);
j = *pi + shift;
/* Defect: Reading a freed pointer */
return j;
}
free
оператор выпускает блок памяти что pi
относится к. Поэтому dereferencingpi
после free
оператор не допустим.
Коррекция — свободный указатель после использования
Одна возможная коррекция должна освободить указатель pi
только после последнего экземпляра, где к этому получают доступ.
#include <stdlib.h>
int increment_content_of_address(int base_val, int shift)
{
int j;
int* pi = (int*)malloc(sizeof(int));
if (pi == NULL) return 0;
*pi = base_val;
j = *pi + shift;
*pi = 0;
/* Fix: The pointer is freed after its last use */
free(pi);
return j;
}