exponenta event banner

CERT C: ARR36-C правил

Не вычитайте и не сравнивайте два указателя, которые не ссылаются на один и тот же массив

Описание

Определение правила

Не вычитайте и не сравнивайте два указателя, которые не ссылаются на один и тот же массив. [1 ]

Внедрение Polyspace

Эта проверка проверяет вычитание или сравнение указателей на различные массивы.

Примеры

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

Проблема

Вычитание или сравнение указателей на различные массивы происходит при вычитании или сравнении указателей, которые являются нулевыми или указывают на элементы в различных массивах. Реляционные операторы для сравнения: >, <, >=, и <=.

Риск

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

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

Прежде чем вычитать или использовать реляционные операторы для сравнения указателей с элементами массива, убедитесь, что они не имеют значения NULL и указывают на один и тот же массив.

Пример - Вычитание между указателями на элементы в различных массивах
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE20 20

size_t func(void)
{
    int nums[SIZE20];
    int end;
    int *next_num_ptr = nums;
    size_t free_elements;
	/* Increment next_num_ptr as array fills */
	
	/* Subtraction operation is undefined unless array nums 
	is adjacent to variable end in memory. */
    free_elements = &end - next_num_ptr; 
    return free_elements;
}
    
      

В этом примере массив nums постепенно заполняется. Затем вычитание указателя используется для определения количества оставшихся свободных элементов. Если end указывает на ячейку памяти, расположенную за последним элементом numsоперация вычитания не определена.

Исправление - вычитание указателей на один и тот же массив

Вычитание указателя на последний элемент, который был заполнен, из указателя на последний элемент массива.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE20 20

size_t func(void)
{
    int nums[SIZE20];
    int *next_num_ptr = nums;
    size_t free_elements;
	/* Increment next_num_ptr as array fills */
	
	/* Subtraction operation involves pointers to the same array. */
    free_elements = &(nums[SIZE20 - 1]) - next_num_ptr;  
	
    return free_elements + 1;
}
     

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

Группа: Правило 06. Массивы (ARR)
Представлен в R2019a

[1] Данное программное обеспечение было создано компанией MathWorks и включает в себя следующие компоненты: «Веб-сайт SEI CERT-C», © 2017 Университет Карнеги-Меллон, веб-сайт SEI CERT-C + + © 2017 Университет Карнеги-Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги-Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги-Меллон, со специальным разрешением от его Института программного обеспечения.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОНА И/ИЛИ ЕГО ПРОГРАММНОГО ИНЖЕНЕРНОГО ИНСТИТУТА, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ КАК ЕСТЬ. УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБЫХ ВОПРОСОВ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ ТОВАРНОЙ ПРИГОДНОСТИ, ИСКЛЮЧИТЕЛЬНОСТИ ИЛИ РЕЗУЛЬТАТОВ, ПОЛУЧЕННЫХ ОТ ИСПОЛЬЗОВАНИЯ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Данное программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллона или его Институтом разработки программного обеспечения.