exponenta event banner

ISO/IEC TS 17961 [uninitref]

Ссылка на неинициализированную память

Описание

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

Ссылка на неинициализированную память.[1]

Реализация Polyspace

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

  • Неинициализированный указатель.

  • Указатель на неинициализированное значение преобразуется в const.

  • Неинициализированная переменная.

Примеры

расширить все

Проблема

Неинициализированный указатель возникает, когда указателю не назначается адрес перед отсрочкой.

Риск

Если указателю явно не назначен адрес, он указывает на непредсказуемое местоположение.

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

Исправление зависит от первопричины дефекта. Например, вы назначили адрес указателю, но назначение недоступно.

Часто детали результата показывают последовательность событий, которые привели к дефекту. Вы можете реализовать исправление на любом событии в последовательности. Если сведения о результате не отображают историю событий, можно отследить их с помощью опций правого щелчка в исходном коде и просмотреть предыдущие связанные события. Смотрите также Результаты интерпретации Bug Finder в интерфейсе пользователя Polyspace Desktop.

См. примеры исправлений ниже. Рекомендуется инициализировать указатель на NULL при объявлении указателя.

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

Пример - Неинициализированная ошибка указателя
#include <stdlib.h>

int* assign_pointer(int* prev)
{
    int j = 42;
    int* pi;

    if (prev == NULL) 
      {
        pi = (int*)malloc(sizeof(int));
        if (pi == NULL) return NULL;
      }

    *pi = j;                    
    /* Defect: Writing to uninitialized pointer */

    return pi;
}

Если prev не NULL, указатель pi не присваивается адрес. Однако pi определяется на каждом пути выполнения независимо от того, prev является NULL или нет.

Коррекция - Инициализация указателя на каждом пути выполнения

Одной из возможных коррекций является назначение адреса pi когда prev не NULL.

#include <stdlib.h>

int* assign_pointer(int* prev)
{
    int j = 42;
    int* pi;

    if (prev == NULL) 
       {
        pi = (int*)malloc(sizeof(int));
        if (pi == NULL) return NULL;
       } 
    /* Fix: Initialize pi in branches of if statement  */
    else 
        pi = prev;              
    

    *pi = j;

    return pi;
}
Проблема

Указатель на неинициализированное значение, преобразованное в const, возникает, когда указатель на константу (const int*, const char*, и т.д.) присваивается адрес, который еще не содержит значения.

Риск

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

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

Инициализируйте переменную перед присвоением ее адреса указателю на константу.

Пример - Указатель на неинициализированное значение, преобразованный в const
#include<stdio.h>

void Display_Parity()
 {
  int num,parity;
  const int* num_ptr = &num;  
  /* Defect: Address &num does not store a value */

  printf("Enter a number\n:");
  scanf("%d",&num);

  parity=((*num_ptr)%2);
  if(parity==0)
    printf("The number is even.");
  else
    printf("The number is odd.");

 }

num_ptr объявляется как указатель на константу. Однако переменная num не содержит значения, когда num_ptr присваивается адрес &num.

Коррекция - Сохраните значение в адресе перед назначением указателю

Одной из возможных коррекций является получение значения num от пользователя перед &num назначается num_ptr.

#include<stdio.h>

void Display_Parity()
 {
  int num,parity;
  const int* num_ptr;

  printf("Enter a number\n:");
  scanf("%d",&num);

 /* Fix: Assign &num to pointer after it receives a value */ 
  num_ptr=&num;                     
  parity=((*num_ptr)%2);
  if(parity==0)
    printf("The number is even.");
  else
    printf("The number is odd.");
 }

The scanf оператор сохраняет значение в &num. Когда значение сохранено, его законно присвоить &num на num_ptr.

Проблема

Неинициализированная переменная возникает, когда переменная не инициализируется до чтения ее значения.

Риск

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

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

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

Часто детали результата показывают последовательность событий, которые привели к дефекту. Вы можете реализовать исправление на любом событии в последовательности. Если сведения о результате не отображают историю событий, можно отследить их с помощью опций правого щелчка в исходном коде и просмотреть предыдущие связанные события. Смотрите также Результаты интерпретации Bug Finder в интерфейсе пользователя Polyspace Desktop.

См. примеры исправлений ниже. Рекомендуется инициализировать переменную при объявлении.

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

Пример - Неинициализированная ошибка переменной
int get_sensor_value(void)
{
    extern int getsensor(void);
    int command;
    int val;

    command = getsensor();
    if (command == 2) 
      {
        val = getsensor();
      }

    return val;              
    /* Defect: val does not have a value if command is not 2 */
}

Если command не 2, переменная val не назначен. В этом случае возврат значение функции get_sensor_value не определено.

Коррекция - Инициализация во время объявления

Одной из возможных коррекций является инициализация val во время объявления так, чтобы инициализация не обходилась по некоторым путям выполнения.

int get_sensor_value(void)
{
    extern int getsensor(void);
    int command;
    /* Fix: Initialize val */
    int val=0;

    command = getsensor();
    if (command == 2) 
      {
        val = getsensor();
      }

    return val;              
 }

val присваивается начальное значение 0. Когда command не равно 2, функция get_sensor_value возвращает это значение.

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

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

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