exponenta event banner

Целочисленное деление на ноль

Деление целого числа на ноль

Описание

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

Риск

Деление на ноль может привести к сбою программы.

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

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

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

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

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

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

Примеры

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

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

Информация о результатах

Группа: Числовые
Язык: C | C++
По умолчанию: Вкл.
Синтаксис командной строки: INT_ZERO_DIV
Воздействие: Высокое
CWE ID: 189, 369
Представлен в R2013b