Операнд указателя и любой указатель, следующий из адресной арифметики с указателями с помощью того операнда, должны оба обратиться к элементам того же массива
Операнд указателя и любой указатель, следующий из адресной арифметики с указателями с помощью того операнда, должны оба обратиться к элементам того же массива.
Это - неопределенное поведение, когда результат операции адресной арифметики с указателями, которая использует указатель на элемент массива, не указывает на также:
Элемент массива.
Одно прошлое последний элемент массива. Например:
int arr[3]; int* res; res = arr+3; // res points to one beyond arr
Правило применяется к этим операциям. ptr указатель на элемент массива и int_exp целое выражение.
ptr + int_exp
int_exp + ptr
ptr - int_exp
ptr + +
++ ptr
- ptr
ptr--
ptr [int_exp ]
Отдельные объекты, которые не являются частью массива, рассматриваются массивами одного элемента. Например, в этом примере кода, arr_one эквивалентно массиву одного элемента. Polyspace® не отмечает шаг указателя ptr_to_one потому что это указывает на одно прошлое последний элемент arr_one.
void f_incr(int* x){
int* ptr_to_one = x;
++ptr_to_one; // Compliant
}
void func(){
int arr_one=1; // Equivalent to array of one element
f_incr(&arr_one);
}Polyspace не отмечает использование параметров указателя в операциях адресной арифметики с указателями, когда те указатели указывают на массивы. Например, в этом фрагменте кода, использовании &a1[2] в f1 совместимо, когда вы передаете массив f1.
void f1( int* const a1){
int* b= &a1[2]; // Compliant
}
void f2(){
int arr[3] {};
f1(arr);
}В структурах с несколькими элементами Polyspace не отмечает результат операции адресной арифметики с указателями на элементе, который приводит к указателю, который указывает на различный элемент, если указатель указывает в выделенной памяти о структуре или к одному прошлому последний элемент структуры.
Например, в этом фрагменте кода, присвоении на ptr_to_struct совместимо, потому что это остается в myStruct, даже если это указывает вне myStruct.elem1. Используя индекс, больше, чем размерность элемента, чтобы получить доступ к содержимому того элемента, несовместимо, даже если получившийся адрес в выделенной памяти о структуре.
void func(){
struct {
char elem1[10];
char elem2[10];
} myStruct;
char* ptr_to_struct = &myStruct.elem1[11]; //Compliant
// Address of myStruct.elem1[11] is inside myStruct
char val_to_struct = myStruct.elem1[11]; // Non-compliant
}В многомерных массивах Polyspace отмечает любое использование индексов, которые больше, чем размерность подрешетки, чтобы получить доступ к элементу той подрешетки. Polyspace не отмечает присвоение адреса того же самого элемента подрешетки, если адрес в выделенной памяти о массиве верхнего уровня.
Например, в этом фрагменте кода, присвоении на указатель ptr_to_arr совместимо, потому что указатель указывает на адрес, который является в выделенной памяти о multi_arr. Присвоение на переменную arr_val несовместимо, потому что индекс раньше получал доступ к элементу подрешетки (3), больше, чем размерность подрешетки (2).
void func(){
int multi_arr[5][2];
// Assigned memory is inside top level array
int* ptr_to_arr = &multi_arr[2][3]; //Compliant
// Use of index 3 with subarray of size 2
int arr_val = multi_arr[2][3]; // Non-compliant
}Polyspace отмечает разыменовывание указателя, когда тот указатель указывает на одно прошлое последний элемент массива. Например, в этом фрагменте кода, присвоении ptr совместимо, но разыменовывание ptr не. tab+3 одно прошлое последний элемент вкладки.
void derefPtr(){
int tab[3] {};
int* ptr = tab+3; //Compliant
int res = *(tab+3); // Non-compliant
}Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.
| Группа: Выражения |
| Категория: необходимый, автоматизированный |