ISO/IEC TS 17961 [diverr]

Ошибки целочисленного деления

Описание

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

Ошибки целочисленного деления. [1]

Примеры

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

Описание

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

Риск

Деление на нуль может привести к катастрофическому отказу программы.

Фиксация

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

Это - хорошая практика, чтобы проверять на нулевые значения знаменателя перед делением и обработать ошибку. Вместо того, чтобы выполнить деление непосредственно:

res = num/den;
используйте библиотечную функцию, которая обрабатывает нулевые значения знаменателя прежде, чем выполнить деление:
res = div(num, den);

Смотрите примеры мер ниже.

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

Пример - деление целого числа нулем

int fraction(int num)
{
    int denom = 0;
    int result = 0;

    result = num/denom;

    return result;
}

Ошибка деления на нуль происходит в num/denom потому что denom нуль.

Коррекция — проверка перед делением

int fraction(int num)
{
    int denom = 0;
    int result = 0;

    if (denom != 0)
        result = num/denom;

    return result;
}

Перед делением добавьте тест, чтобы видеть, является ли знаменатель нулем, проверяя, прежде чем деление произойдет. Если denom всегда нуль, эта коррекция может произвести дефект мертвого кода в ваших результатах Polyspace®.

Коррекция — знаменатель изменения

Одна возможная коррекция должна изменить значение знаменателя так, чтобы denom не нуль.

int fraction(int num)
{
    int denom = 2;
    int result = 0;

    result = num/denom;

    return result;
}

Пример - операция по модулю с нулем

int mod_arr(int input)
{
    int arr[5];
    for(int i = 0; i < 5; i++)
    {
        arr[i] = input % i;
    }

    return arr[0]+arr[1]+arr[2]+arr[3]+arr[4];
}

В этом примере Polyspace отмечает операцию по модулю как деление на нуль. Поскольку по модулю по сути операция деления, делитель (правый аргумент) не может быть нулем. Операция по модулю использует for индекс цикла как делитель. Однако for цикл запускается в нуле, который не может быть итератором.

Коррекция — делитель проверки перед операцией

Одна возможная коррекция проверяет делитель перед операцией по модулю. В этом примере смотрите если индекс i нуль перед операцией по модулю.

int mod_arr(int input)
{
    int arr[5];
    for(int i = 0; i < 5; i++)
    {
        if(i != 0)
        {
             arr[i] = input % i;
        }
        else
        {
             arr[i] = input;
        }
    }

    return arr[0]+arr[1]+arr[2]+arr[3]+arr[4];
}

Коррекция — делитель изменения

Другая возможная коррекция изменяет делитель в ненулевое целое число. В этом примере добавьте тот в индекс перед % операция, чтобы не делиться на нуль.

int mod_arr(int input)
{
    int arr[5];
    for(int i = 0; i < 5; i++)
    {
         arr[i] = input % (i+1);
    }

    return arr[0]+arr[1]+arr[2]+arr[3]+arr[4];
}

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

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

Введенный в R2019a


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