Main Content

CERT C: Rec. ARR00-C

R2026b

Understand how arrays work

Since R2026b

Description

Understand how arrays work1

Polyspace Implementation

Polyspace® checks for these issues:

  • Array access out of bounds

  • Incorrect syntax of flexible array member size

Examples

expand all

Issue

This issue occurs when an array index falls outside the range 0 to (size of array - 1) during array access.

Risk

Accessing an array outside its bounds is undefined behavior. Array access out of bounds can result in reading an unpredictable value, or trying to access a location that is not allowed by your operating system, which can cause a segmentation fault.

Fix

The fix depends on the root cause of the defect. For instance, you accessed an array inside a loop and one of these situations happened:

  • The upper bound of the loop is too large.

  • You used an array index that is the same as the loop index instead of being one less than the loop index.

To fix the issue, you have to modify the loop bound or the array index.

Another reason why an array index can exceed array bounds is an earlier conversion from signed to unsigned integers. The conversion can result in a wraparound of the index value, eventually causing the array index to exceed the array bounds.

Often, the result details show a sequence of events that lead to the defect. You can implement the fix on any event in the sequence. If the result details do not show the event history, you can trace back using the context menu in the source code and see previous related events. See also Interpret Polyspace Bug Finder Results in Polyspace Platform User Interface.

See examples of fixes below.

If you do not want to fix the issue, add comments to your result or code to avoid another review. See:

Example — Accessing Array Out of Bounds
#include <stdio.h>

void fibonacci(void)
{
    int i;
    int fib[10];
 
    for (i = 0; i < 10; i++) 
       {
        if (i < 2) 
            fib[i] = 1;
         else 
            fib[i] = fib[i-1] + fib[i-2];
       }

    printf("The 10-th Fibonacci number is %i .\n", fib[i]);    // Noncompliant

}

The array fib has a size of 10. The greatest allowable array index for fib is 9. After the for-loop, the variable i has value 10 and the printf statement attempts to access fib[10].

Correction — Keep Array Index Within Array Bounds

One possible correction is to print fib[i-1] instead of fib[i] after the for-loop.

#include <stdio.h>

void fibonacci(void)
{
   int i;
   int fib[10];

   for (i = 0; i < 10; i++) 
    {
        if (i < 2) 
            fib[i] = 1;
        else 
            fib[i] = fib[i-1] + fib[i-2];
    }

   
    printf("The 10-th Fibonacci number is %i .\n", fib[i-1]); //compliant
}

The printf statement accesses fib[9] instead of fib[10].

Issue

This issue occurs when you do not use 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, as in int data[]. Before C99, some compilers provided nonstandard ways to define flexible arrays, such as arrays of size one (int data[1]) or zero (int data[0]). This usage is not compliant with the C standards since C99.

Risk

If you define flexible array members by declaring arrays of 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 only one int variable. If you try to write beyond this buffer, you can cause array access out of bounds.

Fix

To implement a flexible array member in a structure, define an array of unspecified size. The structure must have at least 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 1. Compilers that do not recognize this syntax treat data as an array with one element. The assignment statement structP->data[i] = 1 can write to the member data beyond the first array element and cause out of bounds array errors.

Correction — Use Standard C Syntax to Define Flexible Array

Define structures with flexible array members with unspecified size using C99 syntax.


#include <stdlib.h>

struct flexArrayStruct{
  int num;
  int data[];   //Compliant
};

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: Rec. 06. Arrays (ARR)
PQL Name: std.cert.ARR00_C

Version History

Introduced in R2026b


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.