Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The sizeof operator yields the size (in bytes) of its operand, which may 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.

Non-Compliant Code Example

...

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.

Code Block
bgColor#FFcccc
langc
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:

Code Block
bgColor#ccccff
langc
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:

Code Block
bgColor#FFcccc
langc
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):

Code Block
bgColor#ccccff
langc
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;
}

...

Compliant Solution

...

Risk Assessment

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

Recommendation

Severity

Likelihood

Detectable

Remediation Cost

Repairable

Priority

Level

ARR00

ARR01-

A

3 (high)

2 (probable)

3 (low)

P18

L1

C

High

Probable

No

Yes

P12

L1

Automated Detection

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V
sizeof-array-parameter
Fully checked
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-ARR01Fully implemented
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

LANG.TYPE.SAP

sizeof Array Parameter
Compass/ROSE



Can detect violations of the recommendation but cannot distinguish between incomplete array declarations and pointer declarations

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C1321


Klocwork
Include Page
Klocwork_V
Klocwork_V
CWARN.MEMSET.SIZEOF.PTRFully implemented
LDRA tool suite
Include Page
LDRA_V
LDRA_V

401 S

Fully implemented

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-ARR01-a

Do not call 'sizeof' on a pointer type

PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

682, 882

Fully supported

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rec. ARR01-C


Checks for:

  • Wrong type used in sizeof
  • Possible misuse of sizeof

Rec, fully covered.

Splint
Include Page
Splint_V
Splint_V



PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V511, V512, V514, V568, V579, V604, V697, V1086
RuleChecker
Include Page
RuleChecker_V
RuleChecker_V
sizeof-array-parameterFully checked

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

...

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

CERT CCTR01-CPP. Do not apply the sizeof operator to a pointer when taking the size of an arrayPrior to 2018-01-12: CERT: Unspecified Relationship
CWE 2.11CWE-467, Use of sizeof() on a pointer typePrior to 2018-01-12: CERT:
ISO/IEC TS 17961Taking the size of a pointer to determine the size of the pointed-to type [sizeofptr]Prior to 2018-01-12: CERT: Unspecified Relationship
MITRE CWECWE-569Prior to 2018-01-12:
MITRE CWECWE-783Prior 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"


...

Image Added Image Added Image Added