Формирование или использование выключенных указателей или индексов массива
Формирование или использование выключенных указателей или индексов массива.[1]
Эта проверка проверяет на наличие следующих проблем:
Доступ к массиву вне границ.
Доступ к указателям вне границ.
Доступ к массиву вне границ происходит, когда индекс массива падает за пределы области значений [0...array_size-1]
во время доступа к массиву.
Доступ к массиву за его пределами является неопределенным поведением. Можно считать непредсказуемое значение или попытаться получить доступ к расположению, которое не разрешено, и столкнуться с отказом сегментации.
Исправление зависит от первопричины дефекта. Например, вы получили доступ к массиву внутри цикла, и произошла одна из следующих ситуаций:
Верхняя граница цикла слишком велика.
Вы использовали индекс массива, который совпадает с индексом цикла, а не на один меньше, чем индекс цикла.
Чтобы исправить проблему, вы должны изменить связанный цикл или индекс массива.
Другой причиной, по которой индекс массива может превысить границы массива, является предшествующее преобразование из подписанных в беззнаковые целые числа. Преобразование может привести к переносу значения индекса, в конечном счете заставляя индекс массива превысить границы массива.
Часто детали результата показывают последовательность событий, которые привели к дефекту. Вы можете реализовать исправление на любом событии в последовательности. Если сведения о результате не отображают историю событий, можно отследить их с помощью опций правого щелчка в исходном коде и просмотреть предыдущие связанные события. Смотрите также Результаты интерпретации Bug Finder в интерфейсе пользователя Polyspace Desktop.
См. примеры исправлений ниже.
Если вы не хотите устранять проблему, добавьте комментарии к своему результату или коду, чтобы избежать другой проверки. Смотрите Адрес Результаты Polyspace через исправления ошибок или обоснования.
#include <stdio.h>
void fibonacci(void)
{
int i;
int fib[10];
for (i = 0; i < 10; i++)
{
if (i < 2)
fib[i] = 1;
else
fib[i] = fib[i-1] + fib[i-2];
}
printf("The 10-th Fibonacci number is %i .\n", fib[i]);
/* Defect: Value of i is greater than allowed value of 9 */
}
Область массива fib
присваивается размер 10. Индекс массива для fib
имеет допустимые значения [0,1,2,...,9]
. Переменная i
имеет значение 10, когда оно выходит из for
-цикл. Поэтому printf
оператор пытается получить доступ к fib[10]
через i
.
Одной из возможных коррекций является печать fib[i-1]
вместо fib[i]
после for
-цикл.
#include <stdio.h> void fibonacci(void) { int i; int fib[10]; for (i = 0; i < 10; i++) { if (i < 2) fib[i] = 1; else fib[i] = fib[i-1] + fib[i-2]; } /* Fix: Print fib[9] instead of fib[10] */ printf("The 10-th Fibonacci number is %i .\n", fib[i-1]); }
The printf
доступ к оператору fib[9]
вместо fib[10]
.
Доступ к указателю вне границ происходит, когда указатель разыменован вне его границ.
Когда указателю назначается адрес, с указателем ассоциируется блок памяти. Вы не можете получить доступ к памяти за пределами этого блока с помощью указателя.
Удаление указателя за его пределы является неопределенным поведением. Можно считать непредсказуемое значение или попытаться получить доступ к расположению, которое не разрешено, и столкнуться с отказом сегментации.
Исправление зависит от первопричины дефекта. Например, вы разобрали указатель внутри цикла, и произошла одна из следующих ситуаций:
Верхняя граница цикла слишком велика.
Вы использовали арифметику указателя для продвижения указателя с неправильным значением шага указателя.
Чтобы исправить проблему, вы должны изменить привязку цикла или значение шага указателя.
Часто детали результата показывают последовательность событий, которые привели к дефекту. Вы можете реализовать исправление на любом событии в последовательности. Если сведения о результате не отображают историю событий, можно отследить их с помощью опций правого щелчка в исходном коде и просмотреть предыдущие связанные события. Смотрите также Результаты интерпретации Bug Finder в интерфейсе пользователя Polyspace Desktop.
См. примеры исправлений ниже.
Если вы не хотите устранять проблему, добавьте комментарии к своему результату или коду, чтобы избежать другой проверки. Смотрите Адрес Результаты Polyspace через исправления ошибок или обоснования.
int* Initialize(void)
{
int arr[10];
int *ptr=arr;
for (int i=0; i<=9;i++)
{
ptr++;
*ptr=i;
/* Defect: ptr out of bounds for i=9 */
}
return(arr);
}
ptr
присваивается адрес arr
который указывает на блок памяти размером 10*sizeof(int)
. В for
-цикл, ptr
увеличивается в 10 раз. В последней итерации цикла ptr
точки вне назначенного ему блока памяти. Поэтому его нельзя отрешать.
Одна из возможных коррекций состоит в том, чтобы изменить порядок шага и дереференции ptr
.
int* Initialize(void) { int arr[10]; int *ptr=arr; for (int i=0; i<=9;i++) { /* Fix: Dereference pointer before increment */ *ptr=i; ptr++; } return(arr); }
После последнего шага, хотя ptr
точки вне назначенного ему блока памяти, больше он не разыгрывается.
Решимость: Undecidable |
[1] Выдержки из стандарта «Техническая спецификация ISO/IEC TS 17961 - 2013-11-15» воспроизводятся с согласия АФНОР. Только оригинальный и полный текст стандарта, опубликованный AFNOR Editions - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.