ISO/IEC TS 17961 [uninitref]

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

Описание

Управляйте определением

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

Реализация Polyspace

Это средство проверки проверяет на эти проблемы:

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

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

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

Примеры

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

Проблема

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

Риск

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

Фиксация

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

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

Смотрите примеры мер ниже. Это - хорошая практика, чтобы инициализировать указатель на 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 isNull или нет.

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

Одна возможная коррекция должна присвоить адрес 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.");
 }

scanf оператор хранит значение в &num. Если значение хранится, законно присвоить &num к num_ptr.

Проблема

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

Риск

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

Фиксация

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

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

Смотрите примеры мер ниже. Это - хорошая практика, чтобы инициализировать переменную в объявлении.

Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты 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 возвращает это значение.

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

Разрешимость: неразрешимый

Введенный в R2019a


[1]  Выписки из стандарта "Техническая характеристика ISO/IEC TS 17961 - 2013-11-15" воспроизводятся с соглашением о AFNOR. Только исходный и полный текст стандарта, как опубликовано Выпусками AFNOR - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.