CERT C: Rec. ARR02-C

Явным образом задайте границы массивов, даже если неявно заданный инициализатором

Описание

Управляйте определением

Явным образом задайте границы массивов, даже если неявно заданный инициализатором. [1]

Примеры

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

Описание

Проблема происходит, когда вы объявляете массив с внешним рычажным устройством, но вы явным образом не задаете его размер.

Средство проверки правила отмечает массивы, объявленные с помощью extern спецификатор, если объявление явным образом не задает размер массивов.

Риск

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

Пример - объявления массива

extern int32_t array1[10];    /*  Compliant  */
extern int32_t array2[];      /*  Non-compliant  */

В этом примере два массива объявляются array1 и array2. array1 имеет внешнее рычажное устройство (extern ключевое слово) и размер 10. array2 также имеет внешнее рычажное устройство, но никакой заданный размер. array2 несовместимо, потому что для массивов с внешним рычажным устройством, необходимо явным образом задать размер.

Описание

Проблема происходит, когда вы используете обозначенные инициализаторы, чтобы инициализировать объект массивов, но вы не делаете explicitely задают размер массива.

Риск

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

Пример - Используя обозначенные инициализаторы, не задавая размер массивов

int a[5] = {[0]= 1, [2] = 1, [4]= 1, [1] = 1};        /* Compliant */
int b[] = {[0]= 1, [2] = 1, [4]= 1, [1] = 1};         /* Non-compliant */
int c[] = {[0]= 1, [1] = 1, [2]= 1, [3]=0, [4] = 1};  /* Non-compliant */

void display(int);

void main() {
    func(a,5);
    func(b,5);
    func(c,5);
}

void func(int* arr, int size) {
    for(int i=0; i<size; i++)
        display(arr[i]);
}

В этом примере правило нарушено когда массивы b и c инициализируются с помощью обозначенных инициализаторов, но размер массивов не задан.

Описание

Неподходящая инициализация массивов происходит, когда Polyspace® Bug Finder™ полагает, что инициализация массивов с помощью инициализаторов является неправильной.

Этот дефект применяется к нормальным и обозначенным инициализаторам. В C99, с обозначенными инициализаторами, можно поместить элементы инициализатора массивов в любом порядке и неявно инициализировать некоторые элементы массива. Обозначенные инициализаторы используют индекс массива, чтобы установить соответствие между элементом массива и элементом инициализатора массивов. Например, оператор int arr[6] = { [4] = 29, [2] = 15 } эквивалентно int arr[6] = { 0, 0, 15, 0, 29, 0 }.

Можно использовать инициализаторы неправильно одним из следующих способов.

ПроблемаРискВозможная фиксация

В вашем инициализаторе для одномерного массива у вас есть больше элементов, чем размер массивов.

Неиспользованные элементы инициализатора массивов указывают на возможную ошибку кодирования.

Увеличьте размер массивов или удалите избыточные элементы.

Вы помещаете фигурные скобки, заключающие значения инициализатора неправильно.

Из-за неправильного размещения фигурных скобок не используются некоторые элементы инициализатора массивов.

Неиспользованные элементы инициализатора массивов указывают на возможную ошибку кодирования.

Поместите фигурные скобки правильно.

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

Неявная инициализация первого элемента массива указывает на возможную ошибку кодирования. Вы возможно пропустили то, что индексация массива запускается от 0.

Инициализируйте все элементы явным образом.

В вашем обозначенном инициализаторе вы инициализируете элемент дважды.

Первая инициализация заменена.

Избыточная первая инициализация указывает на возможную ошибку кодирования.

Удалите избыточную инициализацию.

Вы используете обозначенные и необозначенные инициализаторы в той же инициализации.

Вы или другой рецензент вашего кода не можете определить размер массива контролем.

Используйте или обозначенные или необозначенные инициализаторы.

Фиксация

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

Смотрите примеры мер ниже.

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

Пример - неправильно помещенные фигурные скобки (C только)


int arr[2][3]
= {{1, 2},
    {3, 4},
    {5, 6}
};

В этом примере, массив arr инициализируется как {1,2,0,3,4,0}. Поскольку инициализатор содержит {5,6}, вы можете ожидать, что массивом будет инициализированный {1,2,3,4,5,6}.

Коррекция — фигурные скобки места правильно

Одна возможная коррекция должна поместить фигурные скобки правильно так, чтобы все элементы были явным образом инициализированы.

int a1[2][3]
= {{1, 2, 3},
    {4, 5, 6}
};

Пример - первый элемент, не явным образом инициализированный

int arr[5]
= {
    [1] = 2,      
    [2] = 3,
    [3] = 4,
    [4] = 5
};              

В этом примере, arr[0] явным образом не инициализируется. Возможно, что программист не полагал, что индексация массива запускается от 0.

Коррекция — явным образом инициализирует все элементы

Одна возможная коррекция должна инициализировать все элементы явным образом.

int arr[5]
= {
    [0] = 1,
    [1] = 2,      
    [2] = 3,
    [3] = 4,
    [4] = 5
};              

Пример - элемент, инициализированный дважды

int arr[5]
= {
    [0] = 1,
    [1] = 2,      
    [2] = 3,
    [2] = 4,
    [4] = 5
};              

В этом примере, arr[2] инициализируется дважды. Первая инициализация заменена. В этом случае, потому что arr[3] не был явным образом инициализирован, возможно, что программист намеревался инициализировать arr[3] когда arr[2] был инициализирован во второй раз.

Коррекция — фиксирует избыточную инициализацию

Одна возможная коррекция должна устранить избыточную инициализацию.

int arr[5]
= {
    [0] = 1,
    [1] = 2,
    [2] = 3,
    [3] = 4,
    [4] = 5
};

Пример - соединение обозначенных и необозначенных инициализаторов

int arr[]
= {
    [0] = 1,
    [3] = 3,
    4,
    [5] = 5,
    6
    };              

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

Коррекция — использует только обозначенные инициализаторы

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

int arr[]
= {
    [0] = 1,
    [3] = 3,
    [4] = 4,
    [5] = 5,
    [6] = 6
};              

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

Группа: Rec. 06. Массивы (ARR)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.