Incorrect syntax of flexible array member size

Гибкий массив представителя заданный с нулем или одним размером

Описание

Этот дефект возникает, когда вы не используете стандартный синтаксис C для определения структуры с гибким представителем массива.

Начиная с C99, можно задать представителя гибкого массива с неопределенным размером. Для образца, desc является гибким представителем массива в этом примере:

struct record {
    size_t len;
    double desc[]; 
};
До C99 вы могли использовать специфические для компилятора методы для определения гибких массивов. Например, вы использовали массивы первого или нулевого размера:
struct record {
    size_t len;
    double desc[0]; 
};
Это использование не соответствует стандартам C, следующим C99.

Риск

Если вы задаете гибкие представители массива при помощи размера zero или one, ваша реализация зависит от компилятора. Для компиляторов, которые не распознают синтаксис, int массив размера 1 имеет буфер для одного int переменная. Если вы пытаетесь записать за пределы этого буфера, можно столкнуться с проблемами, связанными с доступом к массиву вне границ.

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

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

Чтобы реализовать гибкий представитель массива в структуре, задайте массив неопределенного размера. Структура должна иметь один представитель, кроме массива, и массив должен быть последним представителем структуры.

Примеры

расширить все

#include <stdlib.h>
  
struct flexArrayStruct {
  int num;
  int data[1];
};

unsigned int max_size = 100;
 
void func(unsigned int array_size) {
  if(array_size<= 0 || array_size > max_size)  
      exit(1);
  /* Space is allocated for the struct */
  struct flexArrayStruct *structP
    = (struct flexArrayStruct *)
     malloc(sizeof(struct flexArrayStruct)
          + sizeof(int) * (array_size - 1));
  if (structP == NULL) {
    /* Handle malloc failure */
    exit(2);
  }
   
  structP->num = array_size;
 
  /*
   * Access data[] as if it had been allocated
   * as data[array_size].
   */
  for (unsigned int i = 0; i < array_size; ++i) {
    structP->data[i] = 1;
  }
  
  free(structP);
}

В этом примере гибкий массив представителя data определяется значением размера единицы. Компиляторы, которые не распознают этот синтаксис, обрабатывают data как массив размера один. Оператор structP->data[i] = 1; можно записать в data за пределами первого представителя массива и вызвать проблемы с выходом из массива.

Коррекция - используйте синтаксис стандартного C для определения гибкого массива

Задайте гибкие представителей массива с неопределенным размером.

#include <stdlib.h>
  
struct flexArrayStruct{
  int num;
  int data[];
};

unsigned int max_size = 100;
 
void func(unsigned int array_size) {
  if(array_size<=0 || array_size > max_size)  
      exit(1);
  
  /* Allocate space for structure */
  struct flexArrayStruct *structP
    = (struct flexArrayStruct *)
    malloc(sizeof(struct flexArrayStruct)
         + sizeof(int) * array_size);
         
  if (structP == NULL) {
    /* Handle malloc failure */
    exit(2);
  }
 
  structP->num = array_size;
 
  /*
   * Access data[] as if it had been allocated
   * as data[array_size].
   */
  for (unsigned int i = 0; i < array_size; ++i) {
    structP->data[i] = 1;
  }
  
  free(structP);
}

Информация о результатах

Группа: Хорошая практика
Язык: C (проверка отключена, если анализ запускается на C90 коде, обозначенном опцией -c-version c90)
По умолчанию: Off
Синтаксис командной строки : FLEXIBLE_ARRAY_MEMBER_INCORRECT_SIZE
Влияние: Низкое
Введенный в R2018b