CertC-ARR01

Do not apply the sizeof operator to a pointer when taking the size of an array

Required inputs: IR

The sizeof operator yields the size (in bytes) of its operand, which can be an expression or the parenthesized name of a type. However, using the sizeof operator to determine the size of arrays is error prone.

The  sizeof operator is often used in determining how much memory to allocate via  malloc(). However using an incorrect size is a violation of  MEM35-C. Allocate sufficient memory for an object.

Noncompliant Code Example

In this noncompliant code example, the function clear() zeros the elements in an array. The function has one parameter declared as int array[] and is passed a static array consisting of 12 int as the argument. The function clear() uses the idiom sizeof(array) / sizeof(array[0]) to determine the number of elements in the array. However, array has a pointer type because it is a parameter. As a result, sizeof(array) is equal to the sizeof(int *). For example, on an architecture (such as IA-32) where the sizeof(int) == 4 and the sizeof(int *) == 4, the expression sizeof(array) / sizeof(array[0]) evaluates to 1, regardless of the length of the array passed, leaving the rest of the array unaffected.

void clear(int array[]) {
  for (size_t i = 0; i < sizeof(array) / sizeof(array[0]); ++i) {
     array[i] = 0;
   }
}

void dowork(void) {
  int dis[12];

  clear(dis);
  /* ... */
}

Footnote 103 in subclause 6.5.3.4 of the C Standard [ ISO/IEC 9899:2011] applies to all array parameters:

When applied to a parameter declared to have array or function type, the sizeof operator yields the size of the adjusted (pointer) type.

Compliant Solution

In this compliant solution, the size of the array is determined inside the block in which it is declared and passed as an argument to the function:

void clear(int array[], size_t len) {
  for (size_t i = 0; i < len; i++) {
    array[i] = 0;
  }
}

void dowork(void) {
  int dis[12];

  clear(dis, sizeof(dis) / sizeof(dis[0]));
  /* ... */
}

This sizeof(array) / sizeof(array[0]) idiom will succeed provided the original definition of array is visible.

Noncompliant Code Example

In this noncompliant code example, sizeof(a) does not equal 100 * sizeof(int), because the sizeof operator, when applied to a parameter declared to have array type, yields the size of the adjusted (pointer) type even if the parameter declaration specifies a length:

enum {ARR_LEN = 100};

void clear(int a[ARR_LEN]) {
  memset(a, 0, sizeof(a)); /* Error */
}

int main(void) {
  int b[ARR_LEN];
  clear(b);
  assert(b[ARR_LEN / 2]==0); /* May fail */
  return 0;
}
Compliant Solution

In this compliant solution, the size is specified using the expression len * sizeof(int):

enum {ARR_LEN = 100};

void clear(int a[], size_t len) {
  memset(a, 0, len * sizeof(int));
}

int main(void) {
  int b[ARR_LEN];
  clear(b, ARR_LEN);
  assert(b[ARR_LEN / 2]==0); /* Cannot fail */
  return 0;
}
Risk Assessment

Incorrectly using the sizeof operator to determine the size of an array can result in a buffer overflow, allowing the execution of arbitrary code.

Recommendation Severity Likelihood Remediation Cost Priority Level
ARR01-C High Probable Low P18 L1
Related Guidelines
Taxonomy Taxonomy item Relationship
CERT C CTR01-CPP. Do not apply the sizeof operator to a pointer when taking the size of an array Prior to 2018-01-12: CERT: Unspecified Relationship
CWE 2.11 CWE-467, Use of sizeof() on a pointer type Prior to 2018-01-12: CERT:
ISO/IEC TS 17961 Taking the size of a pointer to determine the size of the pointed-to type [sizeofptr] Prior to 2018-01-12: CERT: Unspecified Relationship
MITRE CWE CWE-569 Prior to 2018-01-12:
MITRE CWE CWE-783 Prior to 2018-01-12:
Bibliography
[ Drepper 2006] Section 2.1.1, "Respecting Memory Bounds"
[ ISO/IEC 9899:2011] Subclause 6.5.3.4, "The sizeof and _Alignof Operators"
Excerpt from SEI CERT C Coding Standard: Rules for Developing Safe, Reliable, and Secure Systems (2016 Edition) and SEI CERT C Coding Standard [https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/recommendations/arrays-arr/arr01-c], Copyright (C) 1995-2026 Carnegie Mellon University. See section 9.4. "3rd-Party Licenses" in the documentation for full details.

Possible Messages

Key

Text

Severity

Disabled

sizeof_on_array_param

Operand of “sizeof” shall not be an array parameter

None

False

Options