Main Content

CERT C: Rule DCL38-C

Use the correct syntax when declaring a flexible array member

Description

Rule Definition

Use the correct syntax when declaring a flexible array member.1

Polyspace Implementation

The rule checker checks for Incorrect syntax of flexible array member size.

Examples

expand all

Issue

Incorrect syntax of flexible array member size occurs when you do not use the standard C syntax to define a structure with a flexible array member.

Since C99, you can define a flexible array member with an unspecified size. For instance, desc is a flexible array member in this example:

struct record {
    size_t len;
    double desc[]; 
};
Prior to C99, you might have used compiler-specific methods to define flexible arrays. For instance, you used arrays of size one or zero:
struct record {
    size_t len;
    double desc[0]; 
};
This usage is not compliant with the C standards following C99.

Risk

If you define flexible array members by using size zero or one, your implementation is compiler-dependent. For compilers that do not recognize the syntax, an int array of size one has buffer for one int variable. If you try to write beyond this buffer, you can run into issues stemming from array access out of bounds.

If you use the standard C syntax to define a flexible array member, your implementation is portable across all compilers conforming with the standard.

Fix

To implement a flexible array member in a structure, define an array of unspecified size. The structure must have one member besides the array and the array must be the last member of the structure.

Example - Flexible Array Member Defined with Size One
#include <stdlib.h>
  
struct flexArrayStruct {
  int num;
  int data[1]; //Noncompliant
};

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);
}

In this example, the flexible array member data is defined with a size value of one. Compilers that do not recognize this syntax treat data as a size-one array. The statement structP->data[i] = 1; can write to data beyond the first array member and cause out of bounds array issues.

Correction — Use Standard C Syntax to Define Flexible Array

Define flexible array members with unspecified size.

#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);
}

Check Information

Group: Rule 02. Declarations and Initialization (DCL)

Version History

Introduced in R2019a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.