exponenta event banner

CERT C++: ARR39-C

Не добавлять и не вычитать масштабированное целое число в указатель

Описание

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

Не добавляйте и не вычитайте масштабированное целое число в указатель. [1 ]

Внедрение Polyspace

Эта проверка проверяет неверное масштабирование указателя.

Примеры

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

Проблема

Неправильное масштабирование указателя происходит, когда Polyspace ® Bug Finder™ считает, что неявное масштабирование в арифметике указателя игнорируется.

Например, дефект может возникнуть в следующих ситуациях.

СитуацияРискВозможное исправление
Вы используете sizeof оператор в арифметических операциях над указателем.

sizeof возвращает размер типа данных в байтах.

Арифметика указателя уже неявно масштабируется по размеру типа данных указанной переменной. Следовательно, использование sizeof в арифметике указателя дает непреднамеренные результаты.

Не использовать sizeof оператор в арифметике указателя.
Для указателя выполняются арифметические операции, а затем применяется приведение.Арифметика указателя неявно масштабируется. Если это неявное масштабирование не учитывается, приведение результата арифметики указателя приводит к непреднамеренным результатам.Применить приведение перед арифметикой указателя.

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

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

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

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

Пример - Использование sizeof Оператор
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <wchar.h>
#include <stdio.h>



enum { INTBUFSIZE = 80 };
extern int getdata (void);
int buf[INTBUFSIZE];
void foo (void)
{
  int *buf_ptr = buf;

  while (buf_ptr < (buf + sizeof (buf))) {  
    *buf_ptr++ = getdata ();
  }
}

В этом примере операция sizeof(buf) используется для получения указателя на конец массива buf. Выходные данные sizeof(buf) масштабируется по int. Поскольку арифметика указателя неявно масштабирована, вывод sizeof(buf) снова масштабируется по int при добавлении в buf, что приводит к неожиданному поведению. Polyspace помечает использование sizeof оператор.

Исправление - Удалить sizeof Оператор

Одной из возможных корректировок является использование немасштабированных чисел в качестве смещений.

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



enum { INTBUFSIZE = 80 };
extern int getdata (void);
int buf[INTBUFSIZE];
void foo (void)
{
  int *buf_ptr = buf;

  while (buf_ptr < (buf + INTBUFSIZE)) {  
    *buf_ptr++ = getdata ();
  }
}
Пример - Приведение следующей арифметики указателя
int func(void) {
    int x = 0;
    char r = *(char *)(&x + 1);
    return r;
}

В этом примере операция &x + 1 смещения &x около sizeof(int). После выполнения операции результирующий указатель указывает за пределы допустимого буфера. При отмене привязки указателя появляется ошибка доступа указателя за пределами границ на * операция.

Коррекция - Применить литейную форму перед арифметикой указателя

Если требуется получить доступ ко второму байту x, первый актёрский состав &x в char* и затем выполните арифметику указателя. Результирующий указатель смещен на sizeof(char) байты и все еще точки в разрешенном буфере, размер которого sizeof(int) байт.

int func(void) {
    int x = 0;
    char r = *((char *)(&x )+ 1);
    return r;
}

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

Группа: 04. Контейнеры (CTR)
Представлен в R2019a

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

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

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