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;
   }

The 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 для управления количеством скопированных байтов. Смотрите также Результаты интерпретации Bug Finder в интерфейсе пользователя Polyspace Desktop.

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

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

Пример - Недопустимое использование стандартной строки библиотеки Стандартной программы Ошибки
 #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);
 }

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

Решимость: Undecidable
Введенный в R2019a

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