Формирование или использование за пределы указателей или индексов массивов
Формирование или использование за пределы указателей или массива subscripts.[1]
Это средство проверки проверяет на эти проблемы:
Доступ к массиву за пределы.
Доступ к указателю за пределы.
Доступ к массиву за пределы происходит, когда индекс массива выходит за пределы области значений [0...array_size-1]
во время доступа к массиву.
Доступ к массиву вне его границ является неопределенным поведением. Можно считать непредсказуемое значение или попытку получить доступ к местоположению, которое не позволено, и столкнитесь с отказом сегментации.
Фиксация зависит от первопричины дефекта. Например, вы получили доступ к массиву в цикле, и одна из этих ситуаций произошла:
Верхняя граница цикла является слишком большой.
Вы использовали индекс массива, который совпадает с индексом цикла вместо того, чтобы быть тем меньше, чем индекс цикла.
Чтобы устранить проблему, необходимо изменить связанный цикл или индекс массива.
Другой причиной, почему индекс массива может превысить границы массивов, является предшествующее преобразование от со знаком до беззнакового целого. Преобразование может привести к тому, чтобы переносить значения индекса, в конечном счете заставив индекс массива превысить границы массивов.
Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Bug Finder в Пользовательском интерфейсе Рабочего стола Polyspace.
Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты 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]); }
printf
доступы к оператору fib[9]
вместо fib[10]
.
Доступ к указателю за пределы происходит, когда указатель разыменовывается вне его границ.
Когда указатель присвоен адрес, блок памяти сопоставлен с указателем. Вы не можете получить доступ к памяти, кроме того блокируют использование указателя.
Разыменование указателя вне его границ является неопределенным поведением. Можно считать непредсказуемое значение или попытку получить доступ к местоположению, которое не позволено, и столкнитесь с отказом сегментации.
Фиксация зависит от первопричины дефекта. Например, вы разыменовали указатель в цикле, и одна из этих ситуаций произошла:
Верхняя граница цикла является слишком большой.
Вы использовали адресную арифметику с указателями, чтобы усовершенствовать указатель с неправильным значением для шага указателя.
Чтобы устранить проблему, необходимо изменить связанный цикл или значение шага указателя.
Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Bug Finder в Пользовательском интерфейсе Рабочего стола Polyspace.
Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты 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
точки вне блока памяти, присвоенного ему, это не разыменовывается больше.
Разрешимость: неразрешимый |
[1] Выписки из стандарта "Техническая характеристика ISO/IEC TS 17961 - 2013-11-15" воспроизводятся с соглашением о AFNOR. Только исходный и полный текст стандарта, как опубликовано Выпусками AFNOR - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.