exponenta event banner

ISO/IEC TS 17961 [accfree]

Доступ к освобожденной памяти

Описание

Определение правила

Доступ к освобожденной памяти. [1 ]

Внедрение Polyspace

Эта проверка проверяет наличие следующих проблем:

  • Использование ранее освобожденного указателя.

  • Недопустимое использование стандартной подпрограммы строки библиотеки.

Примеры

развернуть все

Проблема

Использование ранее освобожденного указателя происходит при доступе к блоку памяти после освобождения блока с помощью free функция.

Риск

Когда указателю назначается динамическая память с malloc, calloc или reallocуказывает на расположение памяти в куче. При использовании free на этом указателе соответствующий блок памяти освобождается для перераспределения. Попытка доступа к этому блоку памяти может привести к непредсказуемому поведению или даже к сбою сегментации.

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

Исправление зависит от первопричины дефекта. Узнайте, хотите ли вы освободить память позже или выделить другой блок памяти указателю перед доступом.

Рекомендуется после освобождения блока памяти присвоить соответствующий указатель NULL. Перед удалением ссылок проверьте их на наличие значений 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 относится к. Поэтому обособлениеpi после 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;
}
Проблема

При вызове функции библиотеки строк с недопустимыми аргументами происходит недопустимое использование стандартной подпрограммы строк библиотеки.

Риск

Риск зависит от типа недопустимых аргументов. Например, использование strcpy функция с исходным аргументом, превышающим целевой аргумент, может привести к переполнению буфера.

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

Исправление зависит от стандартной библиотечной функции, связанной с дефектом. В некоторых случаях можно ограничить аргументы функции перед вызовом функции. Например, если strcpy функция:

char * strcpy(char * destination, const char* source);
пытается скопировать слишком много байт в целевой аргумент по сравнению с доступным буфером, ограничить исходный аргумент перед вызовом strcpy. В некоторых случаях можно использовать альтернативную функцию, чтобы избежать ошибки. Например, вместо strcpy, вы можете использовать strncpy для управления количеством скопированных байтов. См. также раздел Интерпретация результатов поиска ошибок в интерфейсе пользователя Polyspace Desktop.

См. примеры исправлений ниже.

Если вы не хотите устранять проблему, добавьте комментарии к результату или коду, чтобы избежать другой проверки. См. раздел Результаты анализа пространства адресов с помощью исправлений ошибок или обоснований.

Пример - Ошибка процедуры использования стандартной строки библиотеки
 #include <string.h>
 #include <stdio.h>
 
 char* Copy_String(void)
 {
  char *res;
  char gbuffer[5],text[20]="ABCDEFGHIJKL";

  res=strcpy(gbuffer,text); 
  /* Error: Size of text is less than gbuffer */

  return(res);
 }

Последовательность text больше по размеру, чем gbuffer. Поэтому функция strcpy не удается скопировать text в gbuffer.

Исправление - использовать действительные аргументы

Одной из возможных корректировок является объявление строки назначения gbuffer с размером, равным или большим, чем исходная строка text.

#include <string.h>
 #include <stdio.h>
 
 char* Copy_String(void)
 {
  char *res;
  /*Fix: gbuffer has equal or larger size than text */
  char gbuffer[20],text[20]="ABCDEFGHIJKL";

  res=strcpy(gbuffer,text);

  return(res);
 }

Проверить информацию

Разрешимость: неразрешимая
Представлен в R2019a

[1] Выдержки из стандарта «ISO/IEC TS 17961 Technical Specification - 2013-11-15» воспроизводятся с согласия AFNOR. Нормативную ценность имеет только оригинальный и полный текст стандарта, опубликованный изданиями AFNOR - доступный через веб-сайт www.boutique.afnor.org.