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.

Риск

Если вы задаете члены массива с переменными границами при помощи нулевого размера или один, ваша реализация зависима компилятором. Для компиляторов, которые не распознают синтаксис, int массив размера у каждого есть буфер для одного 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);
}

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

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